Amla, 31, batted for more than eight hours to frustrate the Sri Lankan spinners who shared nine wickets between them to bowl out South Africa for 282 in their first innings.
Sri Lanka, who made 421 in their first essay, were 11-0 at stumps in their second innings for an overall lead of 150.
Off-spinner Dilruwan Perera (5-69) grabbed a five-wicket haul, his second in five Tests, while left-armer Rangana Herath chipped in with 4-71.
For Amla, it was his first century as South Africa's Test captain. He faced 382 balls and hit 12 fours in his marathon effort.
Also Read
His century, also the first by a South African captain in Sri Lanka, proved crucial and helped the visitors avoid the embarrassment of a follow-on.
The South African innings was wrapped up in the final session with Herath having Dale Steyn (30) caught by Kumar Sangakkara and Imran Tahir by Upul Tharanga at deep mid-off.
Sri Lankan openers Kaushal Silva (five) and Upul Tharanga (six) saw off the overs without any hiccups.