If input is indeed limited to times within 24 hours then if start time is larger than end time it means it rolled into another day.  So you can substract Time::Piece objects and adjust if negative
use warnings;
use strict;
use feature 'say';
use Getopt::Long;
use Time::Piece;
GetOptions ( "S=s" => \my $S, "E=s" => \my $E );
my ($tp_beg, $tp_end) = map { 
    my ($time) = /\[gg\s+ ([0-9]+:[0-9]+:[0-9]+) \s+ I\]/x;
    die "Unexpected input format ($_)" if not $time;
    Time::Piece->strptime($time, "%H:%M:%S")
} $S, $E;
my $diff_secs = $tp_end - $tp_beg;
$diff_secs += 24*60*60  if $diff_secs < 0;
say "Difference is $diff_secs secs";
say "Difference is ", sec_in_day_to_hms($diff_secs);
sub sec_in_day_to_hms {  # add ($tt >= 3600*24) branch for multiple days
    my ($tt) = @_;
    my $msg = do {
        if ( $tt >= 3600 ) {
            sprintf("%d:%02d:%02d (hr:min:sec)",
                $tt/3600, ($tt%3600)/60, $tt%60);
        }
        elsif ( $tt >= 60 ) {
            sprintf("%d min %d sec", ($tt%3600)/60, $tt%60);
        } 
        else { sprintf("%d sec", $tt%60); }
    };
    return $msg;
}
Running as in the question
perl time_diff.pl -S "[gg 8:11:03 I]: Copyright" -E "[gg 8:19:03 I]: BT_DEPTH=99 "
prints
Difference is 480 secs
Difference is 8 min 0 sec
If we change 8:19:03 to 6:19:03 (so it rolled all the way by about two hours short of a full day) and run it as
perl time_diff.pl -S "[gg 8:11:03 I]: Copyright" -E "[gg 6:19:03 I]: BT_DEPTH=99 "
then it prints
Difference is 79680 secs
Difference is 22:08:00 (hr:min:sec)
A comment on the code in the question
It firstly has a mistake of defining a variable $start_time also inside an if block
if(my ($start_time) = $start =~ /.../){
and that variable masks (shadows) the one with the same name declared earlier.  After the if block is exited, the earlier $start_time is restored, um, to undef.
When that's used later in the program (for subtraction) it would print warnings -- if you had them on!  Please add
use strict;
use warnings;
to the top of every program.  These are directly helpful.
One simple way to fix that would be to just remove that my -- then the regex's return is assigned indeed to the earlier declared $start_time.  However, I find that there are too many variables introduced for the purpose so I'd suggest to simplify instead.
Then, the possibly negative difference isn't handled, what the question itself asserts.