Playing just his second Test, Gunaratne scored 116 to marshal the tail to good effect and frustrate the Zimbabwean bowlers, before his dismissal brought the end of the Sri Lankan innings on the stroke of tea.
When Rangana Herath opened the bowling and grabbed the wickets of Tino Mawoyo and Hamilton Masakadza to reduce Zimbabwe to 17 for two, the hosts looked to be embarking on one of their trademark batting collapses.
"We would have liked to have a few more wickets down but hopefully we can grab a few early on tomorrow," said Sri Lanka coach Graham Ford.
"We've seen Rangana turn some deliveries this evening, so once he gets a few going he becomes more of a factor."
More From This Section
The tourists began the day on 290 for five, with Gunaratne on 13, and despite losing centurion Dhananjaya de Silva they were able to make rapid progress during the morning session.
Perera was then trapped lbw by Cremer for 34, but Gunaratne went to lunch on 64 having helped Sri Lanka add 124 runs in the session.
After lunch the 30-year-old increased his rate of scoring further in a 75-run stand for the eighth wicket with captain Rangana Herath, who made 27.
Seamer Donald Tiripano had Herath caught behind and then bowled Suranga Lakmal, but No. 11 Lahiru Kumara held on long enough for Gunaratne to reach three figures and carry the score past 500.
Under pressure after two failures in the first Test, Chari not only put up stern resistance, but also took the attack to Sri Lanka.
The right-hander became the first Zimbabwean Test player to hit his first ball for six as he lofted Herath over long-on - then repeated the stroke to go to his maiden Test fifty.
While Chari had two lbw decisions overturned on review, Ervine was generally untroubled as he stroked eight boundaries and the partnership rattled along at 3.7 runs per over.
"We need to turn up for that first hour tomorrow, and then the first session, and try and get through without losing a wicket.