diff --git a/mysql-test/suite/compat/oracle/r/sp.result b/mysql-test/suite/compat/oracle/r/sp.result
new file mode 100644
index 0000000000000000000000000000000000000000..99845551f1bf87ff71927dd29099a96bb4c356e8
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/sp.result
@@ -0,0 +1,68 @@
+SET sql_mode=ORACLE;
+CREATE FUNCTION f1 (a INT) RETURNS CLOB
+BEGIN
+<<label1>>
+BEGIN
+IF a = 1 THEN
+LEAVE label1;
+END IF;
+RETURN 'IS NOT 1';
+END label1;
+RETURN 'IS 1';
+END;
+/
+SELECT f1(1);
+f1(1)
+IS 1
+SELECT f1(2);
+f1(2)
+IS NOT 1
+DROP FUNCTION f1;
+CREATE FUNCTION f1 (a INT) RETURNS INT
+BEGIN
+<<label1>>
+LOOP
+IF a = 2 THEN
+LEAVE label1;
+END IF;
+SET a= a-1;
+END LOOP;
+RETURN a;
+END;
+/
+SELECT f1(4);
+f1(4)
+2
+DROP FUNCTION f1;
+CREATE FUNCTION f1 (a INT) RETURNS INT
+BEGIN
+<<label1>>
+WHILE a>0 DO
+IF a = 2 THEN
+LEAVE label1;
+END IF;
+SET a= a-1;
+END WHILE label1;
+RETURN a;
+END;
+/
+SELECT f1(4);
+f1(4)
+2
+DROP FUNCTION f1;
+CREATE FUNCTION f1 (a INT) RETURNS INT
+BEGIN
+<<label1>>
+REPEAT
+IF a = 2 THEN
+LEAVE label1;
+END IF;
+SET a= a-1;
+UNTIL a=0 END REPEAT;
+RETURN a;
+END;
+/
+SELECT f1(4);
+f1(4)
+2
+DROP FUNCTION f1;
diff --git a/mysql-test/suite/compat/oracle/t/sp.test b/mysql-test/suite/compat/oracle/t/sp.test
new file mode 100644
index 0000000000000000000000000000000000000000..ad55f4006a38aab46a4dd3585cb30ac850c17b39
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/sp.test
@@ -0,0 +1,74 @@
+SET sql_mode=ORACLE;
+
+DELIMITER /;
+CREATE FUNCTION f1 (a INT) RETURNS CLOB
+BEGIN
+  <<label1>>
+  BEGIN
+    IF a = 1 THEN
+      LEAVE label1;
+    END IF;
+    RETURN 'IS NOT 1';
+  END label1;
+  RETURN 'IS 1';
+END;
+/
+DELIMITER ;/
+SELECT f1(1);
+SELECT f1(2);
+DROP FUNCTION f1;
+
+# LOOP WHILE REPEAT
+
+DELIMITER /;
+CREATE FUNCTION f1 (a INT) RETURNS INT
+BEGIN
+  <<label1>>
+  LOOP
+    IF a = 2 THEN
+      LEAVE label1;
+    END IF;
+    SET a= a-1;
+  END LOOP;
+  RETURN a;
+END;
+/
+DELIMITER ;/
+SELECT f1(4);
+DROP FUNCTION f1;
+
+
+DELIMITER /;
+CREATE FUNCTION f1 (a INT) RETURNS INT
+BEGIN
+  <<label1>>
+  WHILE a>0 DO
+    IF a = 2 THEN
+      LEAVE label1;
+    END IF;
+    SET a= a-1;
+  END WHILE label1;
+  RETURN a;
+END;
+/
+DELIMITER ;/
+SELECT f1(4);
+DROP FUNCTION f1;
+
+
+DELIMITER /;
+CREATE FUNCTION f1 (a INT) RETURNS INT
+BEGIN
+  <<label1>>
+  REPEAT
+    IF a = 2 THEN
+      LEAVE label1;
+    END IF;
+    SET a= a-1;
+  UNTIL a=0 END REPEAT;
+  RETURN a;
+END;
+/
+DELIMITER ;/
+SELECT f1(4);
+DROP FUNCTION f1;
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 19cfe41470da44be931410f9ae92e08f4f00e086..0d1b61fdc1a7270e6ef3cf540d89376b0cc0b751 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -1059,6 +1059,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
         opt_component key_cache_name
         sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
         opt_constraint constraint opt_ident
+        label_declaration_oracle
 
 %type <lex_string_with_metadata>
         TEXT_STRING
@@ -3507,7 +3508,7 @@ sp_opt_label:
         ;
 
 sp_labeled_block:
-          label_ident ':' BEGIN_SYM
+          label_declaration_oracle BEGIN_SYM
           {
             LEX *lex= Lex;
             sp_pcontext *ctx= lex->spcont;
@@ -3519,10 +3520,10 @@ sp_labeled_block:
           }
           sp_block_content sp_opt_label
           {
-            if ($6.str)
+            if ($5.str)
             {
-              if (my_strcasecmp(system_charset_info, $6.str, $5->name.str) != 0)
-                my_yyabort_error((ER_SP_LABEL_MISMATCH, MYF(0), $6.str));
+              if (my_strcasecmp(system_charset_info, $5.str, $4->name.str) != 0)
+                my_yyabort_error((ER_SP_LABEL_MISMATCH, MYF(0), $5.str));
             }
           }
         ;
@@ -3675,14 +3676,14 @@ pop_sp_empty_label:
         ;
 
 sp_labeled_control:
-          label_ident ':' LOOP_SYM
+          label_declaration_oracle LOOP_SYM
           {
             if (push_sp_label(thd, $1))
               MYSQL_YYABORT;
           }
           loop_body pop_sp_label
           { }
-        | label_ident ':' WHILE_SYM
+        | label_declaration_oracle WHILE_SYM
           {
             if (push_sp_label(thd, $1))
               MYSQL_YYABORT;
@@ -3690,7 +3691,7 @@ sp_labeled_control:
           }
           while_body pop_sp_label
           { }
-        | label_ident ':' REPEAT_SYM
+        | label_declaration_oracle REPEAT_SYM
           {
             if (push_sp_label(thd, $1))
               MYSQL_YYABORT;
@@ -13808,6 +13809,10 @@ label_ident:
           }
         ;
 
+label_declaration_oracle:
+          SHIFT_LEFT label_ident SHIFT_RIGHT { $$= $2; }
+        ;
+
 ident_or_text:
           ident           { $$=$1;}
         | TEXT_STRING_sys { $$=$1;}