Toronto rebounded from Friday's loss to get its seventh win in its last 10 road games.
Chris Bassitt (12-6) earned the win, going six innings and giving up three hits and three runs (two earned), with six strikeouts.
The Reds had their two-game winning streak snapped.
Williamson (4-3) went 5 2/3 innings, allowing four runs on nine hits while tossing six strikeouts in the loss. It's the most hits Williamson has allowed in his young career.
The Blue Jays used three RBI singles with two outs in the top of the fourth to kick off the scoring. Daulton Varsho, Whit Merrifield and Bo Bichette got the RBIs to lead the rally and give the Blue Jays a 3-0 lead.
Bichette was activated from the injured list earlier on Saturday and played his first game since July 31. The two-time All-Star went 1-for-5 with the RBI single.
The Reds used a three-run inning of their own in the home half of the inning to pull back even. TJ Friedl laced a leadoff home run to right field, his 11th of the season.
After a Matt McLain walk, Elly De La Cruz hit a ball off the right-field wall and used some of his magic to score. A throwing error by Cavan Biggio allowed McLain to score and De La Cruz to beat the throw and even the score at 3-3.
The Reds flirted with late-game heroics in the bottom of the ninth by getting runners on second and third with no outs thanks to a double steal from newly called-up Noelvi Marter and Christian Encarnacion-Strand.
But Blue Jays closer Jordan Romano retired three straight batters to end the rally and notch his 30th save.
—Field Level Media