Frank Castle (Ray Stevenson) has been the Punisher for six years as the story opens. He assaults a "beat the rap" party for a mob boss, Gaitano Cesare. Billy Russoti (Dominic West) escapes to his recycling plant hideout, and Detectives Martin Soap (Dash Mihok), and Saffiotti (Tony Calabretta), who were staking out the party, inform Castle. Castle infiltrates Russoti's hideout and kills one thug as he is exiting the bathroom. The gunshot alerts Russoti, and a brief fire fight between Castle and him ensues. During the battle, Russoti is thrown into a glass-crushing machine which does not kill him but leaves him hideously disfigured. Russoti later refers to himself as "Jigsaw" because the stitches in his face resemble puzzle pieces. Castle, who has taken cover behind the body of Nicky Donatelli (Romano Orzari), discovers that the first man he killed in the facility was an undercover FBI Agent.
Agent Paul Budiansky (Colin Salmon), the partner of the deceased agent, joins the NYPD's "Punisher Task Force", partnering with Soap to help bring Castle to justice. Meanwhile, a facially mutilated Russoti, recovered from his run-in with the Punisher, frees his deranged brother, "Loony Bin Jim" (Doug Hutchison).
Distraught that he has become the evil he swore to battle, Castle attempts to make reparations to Donatelli's wife, Angela (Julie Benz) and daughter, Grace (Stephanie Janusauskas) to no avail. Castle threatens to retire from the vigilante business, but his armorer, Microchip (Wayne Knight) forces him to reconsider telling him Jigsaw will go after Donatelli's family for revenge.
Jigsaw, Loony Bin Jim, and two goons, Ink and Pittsy, break into Donatelli's house and hold the family hostage. Meanwhile the Punisher tracks down Maginty (T. J. Storm) a known associate of Jigsaw, executing Maginty after he has told what he knows. Agent Budiansky and Detective Soap attempt to arrest the Punisher but are easily disarmed and the Punisher warns Budiansky to leave him alone. Just as the Punisher is about to walk away, Budiansky gets up and handcuffs himself to the Punisher. The Punisher tells him that Jigsaw went after Donatelli's family, but Budiansky sends one police car to check on the Donatelli house, intending to take the Punisher back to the station. When the patrol car fails to respond, he is convinced to check on the house. Budiansky enters the house, and is caught by Ink and Pittsy. Soap frees the Punisher, who kills Ink, and Pittsy and leads Donatelli's wife and daughter away. Budiansky then arrests Jigsaw and Loony Bin Jim after a short gun fight.
Jigsaw and his brother bargain with the FBI for their release by giving up Cristu Bulat (David Vadim), who was smuggling in a biological weapon destined for Arab terrorists in Queens. The brothers are granted total immunity, the $12m Bulat was paying to use Jigsaw's port and a file on Micro. They take Micro hostage, killing his mother in the process. They again take Donatelli family hostage, killing Carlos who Castle had left to protect them. Jigsaw sets himself up in the Bradstreet Hotel, hiring a small private army of criminals, including African-American gangbangers, Irish mobsters and Asian-American thugs all eager to kill the Punisher. Castle enlists the help of Agent Budiansky, who informs Cristu's father, Tiberiu Bulat (Aubert Pallascio), that Jigsaw is located at the Bradstreet Hotel. Tiberiu's goons start a shootout in the hotel's lobby, affording Castle a distraction.
Castle enters by jumping through a second-floor window, leading to a brutal firefight with Jigsaw's hired guns. After the shootout, Loony Bin Jim engages Castle in hand-to-hand combat; he is successful during the first half, but Castle becomes enraged and soon overpowers him. Realizing that he will probably not survive the brawl, Loony Bin Jim runs away. Castle chases him and confronts Jigsaw along with Loony Bin Jim, both holding Micro and Grace Donatelli at gunpoint. Jigsaw gives Castle a choice: If Frank shoots Micro, Jigsaw will let the others go free. Micro boldly offers his life to save the young girl, but Castle chooses to shoot Loony Bin Jim instead. As a result, Jigsaw kills Micro. Enraged by the loss of his partner, Castle attacks Jigsaw, which ends with the Punisher impaling Jigsaw with a metal rod and then throwing him onto a fire. As Jigsaw burns to death, Castle calmly tells him that "This is just the beginning". Outside, Castle is forgiven by Angela and bids farewell to Budiansky and the Donatelli family.
As Castle and Soap walk together, Soap tries to convince Castle to give up his vigilante status after having "killed every criminal in town." Soap however changes his mind when he is attacked by a mugger who quickly becomes another victim of the Punisher