Ricky Nolasco (1-0) came off the disabled list to allow one run and six hits in five innings for the Marlins. He was 0-3 with a 19.73 ERA in four previous appearances against New York.
Willingham tripled with the bases loaded in the first inning against Mike Pelfrey (0-3) and hit a two-run homer off Aaron Heilman in the eighth after the Mets pulled within one. Willingham narrowly missed two more homers, flying out to the warning track in center twice.
"It's one of those things where it's a combination of I feel good at the plate, I'm getting into good hitter's counts a lot of times and getting good pitches to hit," said Willingham, who is hitting .450 with 11 RBIs in his past five games.
Center fielder Alfredo Amezaga leaped high to catch Carlos Beltran's drive near the top of the wall in the fourth, and threw out Carlos Delgado at home to end that inning.
Former Mets prospect Henry Owens pitched the ninth for his third save and second in two days.
David Wright had three hits, including his first home run, for the Mets.
ATLANTA - Cole Hamels bounced back from a rough start to pitch into the eighth inning and Philadelphia finally beat Atlanta.
Hamels (3-1) fell behind 3-0 in the first, giving up a two-run homer to Chipper Jones. He allowed only four more hits the rest of the way, sending the Phillies to their first win over Atlanta in five meetings this season.
Jones homered twice, adding a solo shot in the eighth that finished off Hamels, who went 7 1-3 innings, giving up five of his nine hits in the first. Tom Gordon pitched the ninth for his fifth save.
Mark Redman (0-4) was knocked out during a four-run second and might be in danger of losing his spot in the rotation. His ERA climbed to 10.62 in five starts.
HOUSTON - Bronson Arroyo got his first win of the season and Adam Dunn hit a three-run homer to help Cincinnati beat struggling Houston, which has lost nine of 10.
In his sixth start, Arroyo (1-2) retired the first nine batters before walking Craig Biggio to start the fourth. Arroyo allowed three hits and one run with five strikeouts in seven innings.
Ken Griffey Jr. was back in the lineup after missing three of the past four games because of a chest problem. He went 3-for-3, with a home run and two RBIs, for his first three-hit game of the season.
In the third, Houston starter Matt Albers (0-1) gave up back-to-back homers to Griffey and Alex Gonzalez.
MILWAUKEE - Ben Sheets allowed two runs in six innings after leaving his last start with a groin injury, and Tony Graffanino capped a seven-run sixth inning with a three-run homer for Milwaukee.
Braden Looper (3-2) and St. Louis were cruising with a 2-0 lead in the fifth. But the Cardinals, playing in their second game since the death of reliever Josh Hancock, fell apart again. Milwaukee scored 11 runs over two innings and St. Louis lost its fourth straight.
Sheets (2-2) finished giving up six hits and a walk with three strikeouts and J.J. Hardy had a career-high four hits.
PITTSBURGH - Alfonso Soriano hit his first homer for the Cubs and Cliff Floyd had a go-ahead, two-run shot during a four-run rally in the seventh inning that left Chicago leading Pittsburgh when the game was suspended because of rain.
After a delay of 2 hours, 18 minutes, the game was suspended with the Pirates about to bat in the seventh. It will be finished at 12:35 p.m. today before the teams play their regularly scheduled game.
While the game lasted longer than the required five innings to become official, it was suspended because the Pirates had not yet batted in the seventh.
Soriano, who signed a $136 million contract with Chicago as a free agent in the offseason, needed only one at-bat in May to equal his RBI total in April - one. He was 3-for-4.