diff --git a/lib/rules/padding-line-between-tags.js b/lib/rules/padding-line-between-tags.js
index 3e0994a12..a6144d9a5 100644
--- a/lib/rules/padding-line-between-tags.js
+++ b/lib/rules/padding-line-between-tags.js
@@ -24,44 +24,75 @@ function splitLines(text) {
  * @param {RuleContext} context
  * @param {VElement} tag
  * @param {VElement} sibling
+ * @param {number} lineDifference
  */
-function insertNewLine(context, tag, sibling) {
-  context.report({
-    messageId: 'always',
-    loc: sibling.loc,
-    // @ts-ignore
-    fix(fixer) {
-      return fixer.insertTextAfter(tag, '\n')
-    }
-  })
+function insertNewLine(context, tag, sibling, lineDifference) {
+  const endTag = tag.endTag || tag.startTag
+
+  if (lineDifference === 1) {
+    context.report({
+      messageId: 'always',
+      loc: sibling.loc,
+      // @ts-ignore
+      fix(fixer) {
+        return fixer.insertTextAfter(tag, '\n')
+      }
+    })
+  } else if (lineDifference === 0) {
+    context.report({
+      messageId: 'always',
+      loc: sibling.loc,
+      // @ts-ignore
+      fix(fixer) {
+        const lastSpaces = /** @type {RegExpExecArray} */ (
+          /^\s*/.exec(context.getSourceCode().lines[endTag.loc.start.line - 1])
+        )[0]
+
+        return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`)
+      }
+    })
+  }
 }
 
 /**
  * @param {RuleContext} context
  * @param {VEndTag | VStartTag} endTag
  * @param {VElement} sibling
+ * @param {number} lineDifference
  */
-function removeExcessLines(context, endTag, sibling) {
-  context.report({
-    messageId: 'never',
-    loc: sibling.loc,
-    // @ts-ignore
-    fix(fixer) {
-      const start = endTag.range[1]
-      const end = sibling.range[0]
-      const paddingText = context.getSourceCode().text.slice(start, end)
-      const textBetween = splitLines(paddingText)
-      let newTextBetween = `\n${textBetween.pop()}`
-      for (let i = textBetween.length - 1; i >= 0; i--) {
-        if (!/^\s*$/.test(textBetween[i])) {
-          newTextBetween = `${i === 0 ? '' : '\n'}${
-            textBetween[i]
-          }${newTextBetween}`
+function removeExcessLines(context, endTag, sibling, lineDifference) {
+  if (lineDifference > 1) {
+    let hasOnlyTextBetween = true
+    for (
+      let i = endTag.loc.start.line;
+      i < sibling.loc.start.line - 1 && hasOnlyTextBetween;
+      i++
+    ) {
+      hasOnlyTextBetween = !/^\s*$/.test(context.getSourceCode().lines[i])
+    }
+    if (!hasOnlyTextBetween) {
+      context.report({
+        messageId: 'never',
+        loc: sibling.loc,
+        // @ts-ignore
+        fix(fixer) {
+          const start = endTag.range[1]
+          const end = sibling.range[0]
+          const paddingText = context.getSourceCode().text.slice(start, end)
+          const textBetween = splitLines(paddingText)
+          let newTextBetween = `\n${textBetween.pop()}`
+          for (let i = textBetween.length - 1; i >= 0; i--) {
+            if (!/^\s*$/.test(textBetween[i])) {
+              newTextBetween = `${i === 0 ? '' : '\n'}${
+                textBetween[i]
+              }${newTextBetween}`
+            }
+          }
+          return fixer.replaceTextRange([start, end], `${newTextBetween}`)
         }
-      }
-      return fixer.replaceTextRange([start, end], `${newTextBetween}`)
+      })
     }
-  })
+  }
 }
 
 // ------------------------------------------------------------------------------
@@ -72,11 +103,19 @@ function removeExcessLines(context, endTag, sibling) {
  * @param {RuleContext} context
  */
 function checkNewline(context) {
-  /** @type {Array<{blankLine: "always" | "never", prev: string, next: string}>} */
+  /** @type {Array<{blankLine: "always" | "never" | "consistent", prev: string, next: string}>} */
   const configureList = context.options[0] || [
     { blankLine: 'always', prev: '*', next: '*' }
   ]
 
+  const reverseConfigureList = [...configureList].reverse()
+
+  /**
+   * It has the style of the first `blankLine="consistent"`.
+   * @type {Map<VElement, "always" | "never">}
+   */
+  const firstConsistentBlankLines = new Map()
+
   /**
    * @param {VElement} block
    */
@@ -99,53 +138,36 @@ function checkNewline(context) {
 
     const closestSibling = /** @type {VElement} */ (lowerSiblings[0])
 
-    for (let i = configureList.length - 1; i >= 0; --i) {
-      const configure = configureList[i]
-      const matched =
+    const configure = reverseConfigureList.find(
+      (configure) =>
         (configure.prev === '*' || block.name === configure.prev) &&
         (configure.next === '*' || closestSibling.name === configure.next)
+    )
 
-      if (matched) {
-        const lineDifference =
-          closestSibling.loc.start.line - endTag.loc.end.line
-        if (configure.blankLine === 'always') {
-          if (lineDifference === 1) {
-            insertNewLine(context, block, closestSibling)
-          } else if (lineDifference === 0) {
-            context.report({
-              messageId: 'always',
-              loc: closestSibling.loc,
-              // @ts-ignore
-              fix(fixer) {
-                const lastSpaces = /** @type {RegExpExecArray} */ (
-                  /^\s*/.exec(
-                    context.getSourceCode().lines[endTag.loc.start.line - 1]
-                  )
-                )[0]
-
-                return fixer.insertTextAfter(endTag, `\n\n${lastSpaces}`)
-              }
-            })
-          }
-        } else {
-          if (lineDifference > 1) {
-            let hasOnlyTextBetween = true
-            for (
-              let i = endTag.loc.start.line;
-              i < closestSibling.loc.start.line - 1 && hasOnlyTextBetween;
-              i++
-            ) {
-              hasOnlyTextBetween = !/^\s*$/.test(
-                context.getSourceCode().lines[i]
-              )
-            }
-            if (!hasOnlyTextBetween) {
-              removeExcessLines(context, endTag, closestSibling)
-            }
-          }
-        }
-        break
+    if (!configure) {
+      return
+    }
+    const lineDifference = closestSibling.loc.start.line - endTag.loc.end.line
+
+    let blankLine = configure.blankLine
+    if (blankLine === 'consistent') {
+      const firstConsistentBlankLine = firstConsistentBlankLines.get(
+        block.parent
+      )
+      if (firstConsistentBlankLine == null) {
+        firstConsistentBlankLines.set(
+          block.parent,
+          lineDifference > 1 ? 'always' : 'never'
+        )
+        return
       }
+      blankLine = firstConsistentBlankLine
+    }
+
+    if (blankLine === 'always') {
+      insertNewLine(context, block, closestSibling, lineDifference)
+    } else {
+      removeExcessLines(context, endTag, closestSibling, lineDifference)
     }
   }
 }
@@ -166,7 +188,7 @@ module.exports = {
         items: {
           type: 'object',
           properties: {
-            blankLine: { enum: ['always', 'never'] },
+            blankLine: { enum: ['always', 'never', 'consistent'] },
             prev: { type: 'string' },
             next: { type: 'string' }
           },
diff --git a/tests/lib/rules/padding-line-between-tags.js b/tests/lib/rules/padding-line-between-tags.js
index 18d6743a0..67aa6b228 100644
--- a/tests/lib/rules/padding-line-between-tags.js
+++ b/tests/lib/rules/padding-line-between-tags.js
@@ -17,6 +17,96 @@ const tester = new RuleTester({
 
 tester.run('padding-line-between-tags', rule, {
   valid: [
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <div>
+          <div />
+
+          <div />
+
+          <br/>
+          <br/>
+          <br/>
+          <br/>
+          <br/>
+          <br/>
+
+          <div />
+
+          <div />
+        </div>
+      </template>
+      `,
+      options: [
+        [
+          { blankLine: 'consistent', prev: '*', next: '*' },
+          { blankLine: 'never', prev: 'br', next: 'br' }
+        ]
+      ]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <div>
+          <div />
+        </div>
+      </template>
+      `,
+      options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <div>
+          <div />
+
+          <div />
+        </div>
+      </template>
+      `,
+      options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <header>
+          <div></div>
+
+          <div></div>
+
+          <div></div>
+        </header>
+        <div></div>
+        <div />
+        <footer></footer>
+      </template>
+      `,
+      options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <header>
+          <div></div>
+          <div></div>
+          <div></div>
+        </header>
+
+        <div></div>
+
+        <div />
+
+        <footer></footer>
+      </template>
+      `,
+      options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]]
+    },
     {
       filename: 'test.vue',
       code: `
@@ -1027,6 +1117,185 @@ tester.run('padding-line-between-tags', rule, {
         }
       ],
       options: [[{ blankLine: 'never', prev: '*', next: '*' }]]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <header>
+          <div></div>
+
+          <div></div>
+          <div></div>
+        </header>
+        <div></div>
+        <div />
+        <footer></footer>
+      </template>
+      `,
+      output: `
+      <template>
+        <header>
+          <div></div>
+
+          <div></div>
+
+          <div></div>
+        </header>
+        <div></div>
+        <div />
+        <footer></footer>
+      </template>
+      `,
+      errors: [
+        {
+          message: 'Expected blank line before this tag.',
+          line: 7,
+          column: 11
+        }
+      ],
+      options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <header>
+          <div></div>
+
+          <div></div>
+          <div></div>
+          <div></div>
+          <div></div>
+        </header>
+        <div></div>
+        <div />
+        <footer></footer>
+      </template>
+      `,
+      output: `
+      <template>
+        <header>
+          <div></div>
+
+          <div></div>
+
+          <div></div>
+
+          <div></div>
+
+          <div></div>
+        </header>
+        <div></div>
+        <div />
+        <footer></footer>
+      </template>
+      `,
+      errors: [
+        {
+          message: 'Expected blank line before this tag.',
+          line: 7,
+          column: 11
+        },
+        {
+          message: 'Expected blank line before this tag.',
+          line: 8,
+          column: 11
+        },
+        {
+          message: 'Expected blank line before this tag.',
+          line: 9,
+          column: 11
+        }
+      ],
+      options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <div>
+          <div />
+          <div />
+
+          <br/>
+          <br/>
+
+          <div />
+          <div />
+
+          <div />
+          <div />
+        </div>
+      </template>
+      `,
+      output: `
+      <template>
+        <div>
+          <div />
+          <div />
+          <br/>
+          <br/>
+          <div />
+          <div />
+          <div />
+          <div />
+        </div>
+      </template>
+      `,
+      errors: [
+        {
+          message: 'Unexpected blank line before this tag.',
+          line: 7,
+          column: 11
+        },
+        {
+          message: 'Unexpected blank line before this tag.',
+          line: 10,
+          column: 11
+        },
+        {
+          message: 'Unexpected blank line before this tag.',
+          line: 13,
+          column: 11
+        }
+      ],
+      options: [
+        [
+          { blankLine: 'consistent', prev: '*', next: '*' },
+          { blankLine: 'never', prev: 'br', next: 'br' }
+        ]
+      ]
+    },
+    {
+      filename: 'test.vue',
+      code: `
+      <template>
+        <div>
+          <div />
+          <div />
+
+          <div />
+        </div>
+      </template>
+      `,
+      output: `
+      <template>
+        <div>
+          <div />
+          <div />
+          <div />
+        </div>
+      </template>
+      `,
+      errors: [
+        {
+          message: 'Unexpected blank line before this tag.',
+          line: 7,
+          column: 11
+        }
+      ],
+      options: [[{ blankLine: 'consistent', prev: '*', next: '*' }]]
     }
   ]
 })