Shikhar Dhawan smashed a scintillating century for India but Sri Lanka's spinners struck five times to leave the tourists on edge after the first day of the third Test on Saturday.
Malinda Pushpakumara took three wickets and Lakshan Sandakan two, leaving India on 329-6 at the close, with Wriddhiman Saha on 13 and Hardik Pandya on one.
Pushpakamara rattled the Indian top-order with his left-arm spin after a 188-run opening stand between Dhawan, who hit 119 in 123 balls, and Lokesh Rahul (85).
Left-arm wrist spinner Sandakan's wickets included the prized scalp of Indian skipper Virat Kohli for 42.
The left-right opening partnership of Dhawan and Rahul took India through the first session against a hapless Sri Lankan bowling attack.
Sri Lanka captain Dinesh Chandimal then rotated his spinners in the second session and India lost three top batsmen in just 11 overs.
The 30-year-old Pushpakumara, who made his Test debut in the second Test in Colombo, removed the openers to bring the hosts back into the contest.
Rahul, who scored his seventh consecutive Test fifty, mistimed a drive to mid-on and Dhawan soon followed his partner to the pavilion.
Rahul joined Everton Weekes, Andy Flower, Shivnarine Chanderpaul, Kumar Sangakkara and Chris Rogers on the list of batsmen who have made seven consecutive 50-plus scores in Tests.
Kohli tried to stem the rot during a 84-ball innings, ended when he edged a Sandakan delivery to slip.
India toiled in the last session - the innings run-rate plummeted from around five in the morning session to 2.76 after tea.
Pace spearhead Vishwa Fernando chipped in with the wicket of Ravichandran Ashwin, who was caught behind after a hard-working 31.
India had elected to bat first as they eye a series sweep after taking an unassailable 2-0 lead in Colombo.