Pittsburgh scored twice in the ninth on an RBI double by Jordy Mercer and Frazier's RBI single, both against reliever Brett Cecil (1-3).
Wade LeBlanc (4-2) pitched the ninth for Pittsburgh for the win.
Magneuris Sierra was 4-for-4 with an RBI for St. Louis.
Pittsburgh (44-48), fourth in the National League Central, won the series with two victories during the weekend and moved within a half-game of St. Louis (44-47).
Cardinals starter Carlos Martinez made his 13th quality start, allowing two runs and five hits in seven innings.
Trevor Williams, making his first career start against the Cardinals, allowed two runs and 10 hits in 5 2/3 innings with five strikeouts and two walks. He just missed his fourth quality start in his past five outings.
Andrew McCutchen's 1,400th career hit gave the Pirates a 1-0 lead in the first inning. His one-out single up the middle drove home Frazier, who led off with a bloop single and stole second.
St. Louis tied it in the fifth when Sierra reached on an infield single, advanced on Martinez's bunt and scored on Matt Carpenter's double to the corner in right.
Max Moroff hit Martinez's first pitch of the fifth off the foul pole in left for his first major league homer and a 2-1 Pittsburgh lead.
St. Louis tied it again in the sixth on Kolten Wong's one-out single, Sierra's infield single an out later and Martinez's RBI base hit up the middle. That chased Williams.
Yadier Molina's home run to left in the eighth gave the Cardinals their first lead at 3-2. It was the first homer of the season given up by Pittsburgh reliever Juan Nicasio.
NOTES: RF Magneuris Sierra's infield single in the second inning gave him the distinction of being the first St. Louis player to hit safely in his first nine major league games. He was recalled Saturday from Double-A Springfield. ... Pittsburgh RHP and starter Trevor Williams' single to right field in the third inning was his first major league hit after starting his career 0-for-22. ... 2B Josh Harrison, the Pirates' representative at the All-Star Game last week, and 3B David Freese were given the day off from the starting lineup.