Bryan Rust had a goal and three assists, Jason Zucker had a goal and two assists, and Evgeni Malkin had three assists for the Penguins (13-8-4), who are 7-1-1 in their past nine games. Tristan Jarry made 26 saves.
Pavel Buchnevich and Vladimir Tarasenko scored for the Blues (11-13-0), who have lost three straight and five of their past six games.
Jordan Binnington allowed four goals on 17 shots before being replaced in the second period by Thomas Greiss, who made 19 saves.
"We need a lot more guys to step up and play better," St. Louis coach Craig Berube said. "We had one line going offensively tonight. [Robert] Thomas' line created opportunities, competed hard. We definitely need more guys to step up, help the team win. We don't have enough guys right now. We don't have enough guys. That's everybody. Everybody has to step up.
"Right now, we're not good. We don't have enough people going in the right direction right now in all areas of the game. All of them. Everybody. It's not good enough. Until more guys step up and play better and we start pulling together as a team, it won't change."
Kapanen put Pittsburgh ahead 1-0 at 6:58 of the first period when a shot from Pierre-Olivier Joseph hit his skate and deflected in off Binnington.
Rust made it 2-0 at 11:59, taking the puck away from Blues forward Brandon Saad along the wall and driving to the slot for a snap shot.
Rust had two points (one goal, one assist) in his previous 14 games.
"Anytime you go through stretches like that, it's in the back of your head," Rust said. "But I've gone through stretches like that before and I've gone through stretches much worse."