The only use that I'm aware of is that you can use labels in break or continue statements.  So if you have nested loops, it's a way to break out of more than one level at a time:
OUTER: for (x : xList) {
          for (y : yList) {
              // Do something, then:
              if (x > y) {
                  // This goes to the next iteration of x, whereas a standard
                  // "continue" would go to the next iteration of y
                  continue OUTER;
              }
          }
       }
As the example implies, it's occasionally useful if you're iterating over two things at once in a nested fashion (e.g. searching for matches) and want to continue - or if you're doing normal iteration, but for some reason want to put a break/continue in a nested for loop.
I tend to only use them once every few years, though.  There's a chicken-and-egg in that they can be hard to understand because they're a rarely-used construct, so I'll avoid using labels if the code can be clearly written in another way.