The second century of Williams' test career — 107 — and half-centuries from Sikandar Raza and Brendan Taylor gave Zimbabwe a fighting chance of leveling the two-test series after Sri Lanka won the first by 10 wickets.
Williams played an entertaining innings on a flat pitch, hitting 10 boundaries and four sixes from 137 balls.
From 133-4, Williams and Raza, who made 72, shared a fifth-wicket stand of 151.
Raza was out mishitting offspinner Lasith Embuldeniya, caught by Sri Lanka captain Angelo Mathews running in from long on.
The left-handed Williams perished an hour before stumps after he was bowled by offspinner Dhananjaya de Silva while attempting to sweep.
"It was a fantastic first day. The mindset of our players seems to be changing slowly but surely; it's really enjoyable to be arriving in the changing room these days," Williams said. "It's fun, it's exciting, things are happening, the way they are playing their cricket now is almost fearless.
"Three hundred and fifty in a day, I will take that any day. Six wickets down wasn't good but, again, poor shot selection. I will get myself into this, this time. I know I criticized my players the last time. I played a terrible shot today to get out and exposing two new batsmen to the new ball. Decisions like that have to stop and we have to be accountable for that."
De Silva, meanwhile, also accounted for Craig Ervine (12) to finish the day with figures of 2-67.
Pacer Suranga Lakmal took 2-31, claiming the crucial wickets of opener Kevin Kasuza, who he clean bowled on 38, and Brendan Taylor, who didn't move and was trapped lbw on 62.
"Tomorrow morning is a new day, and I hope to pick wickets quickly, and hopefully we put a decent score on the scoreboard," Lakmal said.
Seamer Lahiru Kumara, who removed Zimbabwe opener Lahiru Kumara, was the other wicket-taker.