Earnhardt led only 11 laps but his No. 88 Chevrolet was the car to beat down the stretch, and he zipped past the dominant Keselowski, who had debris on his grille and a hot engine, with five laps remaining in the 400-mile race. Keselowski was second for the second straight race.
Earnhardt won the Daytona 500 and now has multiple wins in a season for the first time since 2004.
Keselowski has a runner-up finish to go with his 95 laps led. Kurt Busch, Denny Hamlin and rookie Kyle Larson rounded out the top five.
Earnhardt gave Hendrick Motorsports its third straight win, following back-to-back victories by Jimmie Johnson. Johnson overcame a pit road mishap to finish sixth.
"I don't have much to do tomorrow," a grinning Earnhardt said. "Tonight's going to be a long one."
Keselowski had the car to beat in his No. 2 Ford when a piece of trash stuck to his grille. He appeared to yield the lead to Earnhardt in an attempt to clean off the front grille and not lose time. He stalked Earnhardt down the stretch but could never recover, losing his shot at his second win of the season.
"I was trying to make a move to clean it off," Keselowski said. "I realized I made a mistake."
His misjudgment worked out just fine for Earnhardt.
Earnhardt, long NASCAR's most popular driver, gave the Pocono crowd plenty of reason to go wild, pulling away from Keselowski and winning for the first time at the track. Earnhardt said Keselowski may have had the best car — but he had the best one at the end.
''He had me beat. I couldn't get to him," Earnhardt said. "I've lost in some strange ways, so it feels good to win one like that."