At tea, Sri Lanka were reduced to 61 for 4 in 14 overs after Hardik Pandya smashed his maiden Test hundred to take India to a strong total.
India were bowled out in 122.3 overs post lunch.
Pandya was dismissed for 108 runs (96 balls, 8 fours and 7 sixes) after adding 66 runs for the last wicket with Umesh Yadav (3 n.O).
The former was caught at deep cover off Lakshan Sandakan (5-132) three deliveries after the break. It was the Lankan chinaman's maiden five-wicket haul in his 6th Test.
More From This Section
Mohammed Shami (2-15) and Umesh Yadav (0-23) moved the new ball very well and used the bounce available to good effect. Upul Tharanga (5) was the first to go, caught behind off Shami in the 3rd over, albeit he wasted a DRS review despite getting a thick edge.
Shami also sent back Dimuth Karunaratne (4) cheaply, caught behind again in the 5th over. Things took a dire turn for the hosts when Kusal Mendis (18) was run-out after a mix- up with skipper Dinesh Chandimal (13 batting).
Pandya then struck a body blow with the ball as well trapping Angelo Mathews (0) lbw in the 10th over as Lanka were reduced to 38 for 4.
Earlier, as the day began, Pandya and Wriddhiman Saha (16) looked to bat for time in a bid to resurrect India's floundering first innings.
But they could only add 10 more runs to their overnight partnership as Saha was caught at gully off Vishwa Fernando (2-87) off the 9th ball of the morning.
Kuldeep Yadav (26) batted resolutely though and put on 62 runs with Pandya for the 8th wicket. In doing so they took India past 400 in the 110th over, something that seemed unlikely at stumps on day one.
Pandya then went into overdrive and put on 20 runs with Shami (8), whilst reaching his half-century off 61 balls. He then put Malinda Pushpakumara (3-82) to the sword in the 116th over, taking 26 runs off him with 3 sixes and 2 fours.
It was the most runs scored by an Indian batsman in an over in Test cricket, beating the previous joint-record of 24 runs held by Sandip Patil and Kapil Dev.
Pandya then reached his maiden Test hundred off 86 balls, his second half-century coming off only 25 balls. It was also his highest First-Class score. It was also the second fastest Test hundred overseas by an Indian batsman, second to Virender Sehwag's 78-ball effort against West Indies at Gros Islet in 2006.
On day one, Shikhar Dhawan (119) and KL Rahul (85) put on the highest opening stand of 188 runs on Lankan soil as India finished at 329/6 at stumps.