Courtesy Dhawan's (119) sixth Test hundred and a record 18-run opening stand with KL Rahul (85), India looked good for a score close to 400 after opting to bat.
However, some fine bowling in the final two sessions by left-arm spinner Malinda Pushpakumara (3/40 in 18 overs) and chinaman Lakshan Sandakan (2/84 in 25 overs) helped Sri Lanka gain some foothold when stumps were drawn on the opening day.
However, Kohli had been reaching out to play the spinners from his crease and ended up edging the ball to first slip off Sandakan in the 79th over.
Ravichandran Ashwin (31) looked compact but became left- arm seamer Vishwa Fernando's scalp at the fag end of the day.
Ashwin and Wriddhiman Saha (13 batting), who survived a DRS appeal for caught behind, then brought up India's 300 in the 81st over even as the visitors were in dire need of a partnership to make their morning advantage count.
The duo added 26 runs for the 6th wicket and negotiated the second new ball properly as well. But Ashwin was caught behind off Fernando, two overs before stumps leaving India with more work to do on the second day.
Earlier, it was yet another solid start from Dhawan and Rahul as they bettered the highest opening stand against Sri Lanka in away Tests, going past the 173-run stand between Manoj Prabhakar and Navjot Sidhu during the 1993 series.
Rahul missed out on another Test hundred, miscuing one straight to Dimuth Karunaratne at mid-on off left-arm spinner Pushpakumara in the 40th over. His 135-ball knock had eight fours.
Dhawan though stayed and scored his second hundred of this series off 107 balls. He added 31 runs with Cheteshwar Pujara (8) but the latter did not look very comfortable despite good batting conditions.
Dhawan was caught at square leg, thanks to a leaping effort from skipper Dinesh Chandimal, a second dismissal against the run of play as he was just looking to cut loose with a flurry of boundaries.
Dhawan faced 123 balls in his knock and punished the home bowlers with 17 boundaries.
Pujara's discomfort at the crease came to an end as he was caught at first slip off Sandakan in the 51st over.
He put on only 10 runs with Kohli as India were left to rebuild their innings despite being in a comfortable position.
Earlier, Dhawan, who scored at a brisk pace, and Rahul settled down quickly on an easy-paced wicket with true bounce.
Paceman Lahiru Kumara was very expensive in his first six overs, leaking 41 runs while Fernando also could not keep the batsmen in check. So much so that Karunaratne had to be introduced early into the attack and was the best Lankan bowler on display in the morning session.
The opening duo brought up its 50-partnership off just 55 balls in the 10th over and kept up this pace of scoring to reach 100 off 107 balls in the 18th over.
They remained in control even when the hosts introduced spin into the attack in the form of Dilruwan Perera.
For Rahul, it was his seventh successive fifty in Test cricket overtaking Gundapppa Viswanath and Rahul Dravid (both with six half-centuries each).
With Yadav and Sandakan featuring in the match, it is only the second time since 2004 when two 'chinaman' bowlers are playing in the same game after Dave Mohammed (West Indies) and Paul Adams (South Africa) at Cape Town.
(This story has not been edited by Business Standard staff and is auto-generated from a syndicated feed.)