diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp
index f46f469e53f731eff4511bd2e7b2fda487317b8a..c744d292a4ba85d001a7e404958d9310b7dc90ef 100644
--- a/src/plugins/cpptools/cppcodeformatter.cpp
+++ b/src/plugins/cpptools/cppcodeformatter.cpp
@@ -382,6 +382,12 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
             default:            leave(); continue;
             } break;
 
+        case label:
+            switch (kind) {
+            case T_COLON:       leave(); break;
+            default:            leave(); continue; // shouldn't happen
+            } break;
+
         case multiline_comment_start:
         case multiline_comment_cont:
             if (kind != T_COMMENT && kind != T_DOXY_COMMENT) {
@@ -710,6 +716,10 @@ bool CodeFormatter::tryDeclaration()
                 enter(qt_like_macro);
                 return true;
             }
+            if (m_tokens.size() > 1 && m_tokens.at(1).kind() == T_COLON) {
+                enter(label);
+                return true;
+            }
         }
         // fallthrough
     case T_CHAR:
@@ -1428,6 +1438,16 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
                 *indentDepth = 0;
         }
         break;
+    case T_IDENTIFIER:
+        if (topState.type == substatement
+                || topState.type == substatement_open
+                || topState.type == case_cont
+                || topState.type == block_open
+                || topState.type == defun_open) {
+            if (tokens.size() > 1 && tokens.at(1).kind() == T_COLON) // label?
+                *indentDepth = 0;
+        }
+        break;
     }
 }
 
diff --git a/src/plugins/cpptools/cppcodeformatter.h b/src/plugins/cpptools/cppcodeformatter.h
index fa306d2c3400629f343880f4a305b0322aff705c..e828b7b7db6e989bc892fc8615d84dcfcd6dfb8e 100644
--- a/src/plugins/cpptools/cppcodeformatter.h
+++ b/src/plugins/cpptools/cppcodeformatter.h
@@ -112,6 +112,7 @@ public: // must be public to make Q_GADGET introspection work
         cpp_macro_cont, // Subsequent lines of a multi-line C preprocessor macro definition.
         cpp_macro_conditional, // Special marker used for separating saved from current state when dealing with #ifdef
         qt_like_macro, // after an identifier starting with Q_ or QT_ at the beginning of the line
+        label, // after an identifier followed by a colon
 
         defun_open, // Brace that opens a top-level function definition.
         using_start, // right after the "using" token
diff --git a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
index 6c0dd5eff32f98108cd931b475d64d91a2f4c56e..3122b5d22c9acfb180c8db5ff98b5827a7354f6c 100644
--- a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
+++ b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
@@ -57,6 +57,7 @@ private Q_SLOTS:
     void gnuStyleSwitch();
     void whitesmithsStyleSwitch();
     void indentToNextToken();
+    void labels();
 };
 
 struct Line {
@@ -1116,6 +1117,21 @@ void tst_CodeFormatter::indentToNextToken()
     checkIndent(data);
 }
 
+void tst_CodeFormatter::labels()
+{
+    QList<Line> data;
+    data << Line("void foo() {")
+         << Line("lab:")
+         << Line("    int abc;")
+         << Line("def:")
+         << Line("    if (a)")
+         << Line("boo:")
+         << Line("        foo;")
+         << Line("    int j;")
+         ;
+    checkIndent(data);
+}
+
 QTEST_APPLESS_MAIN(tst_CodeFormatter)
 #include "tst_codeformatter.moc"