Here's one that uses almost no storage, by seeking back to the last PATTERN1 and re-reading the input file.
Note that this will not work on a pipe.
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11111545
use warnings;
my $fh = *DATA; # FIXME to your input file, DATA only used for testing
my $lastpattern1;
while( <$fh> )
{
if( /PATTERN1/ )
{
$lastpattern1 = tell($fh) - length $_;
}
elsif( $lastpattern1 and /PATTERN3/ )
{
seek $fh, $lastpattern1, 0;
while( <$fh> )
{
my $end = s/ (?=PATTERN3)/\n\n/;
print;
$end and last;
}
$lastpattern1 = undef;
}
}
__DATA__
PATTERN1 SOME INFO
TEXT1
TEXT2
TEXT3 PATTERN2 SOME INFO
PATTERN1 SOME INFO
TEXT4
TEXT5
TEXT6 PATTERN3 SOME INFO
PATTERN1 SOME INFO
TEXT1
TEXT2
TEXT3 PATTERN4 SOME INFO
PATTERN1 SOME INFO
TEXT4
TEXT55
TEXT6 PATTERN3 SOME INFO
I also do the fix up on the PATTERN3 line, though I'm curious if that was just a typo on your part?