The victory also came after a terrible blunder by four-time series champion and eight-time Martinsville winner Jeff Gordon.
Gordon took the lead for the first time with 58 laps left and then got caught entering pit road too fast when the 16th and final caution came out with about 40 laps to go.
“Wow. I'm sorry guys,” he said on the radio. “That's on me. I apologize.”
The race also ended Kevin Harvick's streak of top-two finishes at eight. Harvick, who was three races shy of tying Richard Petty's record of 11, led a race-high 154 laps, but faded to eighth place.
Dale Earnhardt Jr., who won at the track last fall, wound up in the garage after losing his radiator in a large crash in the first turn before the midpoint of the race, and Jimmie Johnson, an eight-time Martinsville winner, had issues throughout the race and finished 35th, 32 laps down. Earnhardt finished right behind him.
The race also marked the Cup debut of Chase Elliott, who will replace the retiring Gordon in the Hendrick stable next season, and Elliott got a quick welcome. His car was bounced around early, wound up in the garage and he finished 38th.
The day went better for Danica Patrick, who was seventh, her fifth career top-10 finish. That tied her with Janet Guthrie for most top-10s by a female driver, and was one spot off Patrick's career-best sixth place run at Atlanta last year.
Hamlin, unlike Gordon, made his mistake early enough in the race to recover. Before the race was 200 laps old, he was penalized for an uncontrolled tire on pit road and dropped from the lead to 22nd.
He was back in the top 10 by the midpoint, and stalking the leaders shortly thereafter.