In reply to chris_le:
The advantage is the compiler error you get from mismatched labels is much easier to fix then without the labels. This is most useful when there are many levels of nested blocks.
module test;
initial
forever begin
if (a) begin
// stuff
if (b) begin
// more stuff
end else if (c) begin
// even more stuff
end
end
endmodule
Imagine that stuff was many lines of code. The only error message you will get from this is a syntax error pointing to the endmodule. Using begin/end labels makes it harder to make these kind of mistakes and easier for the compiler to point out the incorrectly terminated block. Having end labels also makes it easier to read the code when the starting lablel is not on the same page/screen.