diff --git a/CHANGELOG b/CHANGELOG
index 3188ff68f5645c2384019c92f14f07e3ac48ebe1..0eb7595fbfa3c47e14b31d2e6ef8fcfbb67bf4ec 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -18,6 +18,7 @@ v 8.10.0 (unreleased)
   - Fix MR-auto-close text added to description. !4836
   - Fix issue, preventing users w/o push access to sort tags !5105 (redetection)
   - Add Spring EmojiOne updates.
+  - Add syntax for multiline blockquote using `>>>` fence !3954
   - Fix viewing notification settings when a project is pending deletion
   - Fix pagination when sorting by columns with lots of ties (like priority)
   - The Markdown reference parsers now re-use query results to prevent running the same queries multiple times !5020
diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md
index 236eb7b12c42b1fd9eee8538fe0d3c538775c6f1..fb2dd5827540aa7653e6606ea4fbdf842c4a24db 100644
--- a/doc/markdown/markdown.md
+++ b/doc/markdown/markdown.md
@@ -7,11 +7,12 @@
 * [Newlines](#newlines)
 * [Multiple underscores in words](#multiple-underscores-in-words)
 * [URL auto-linking](#url-auto-linking)
+* [Multiline Blockquote](#multiline-blockquote)
 * [Code and Syntax Highlighting](#code-and-syntax-highlighting)
 * [Inline Diff](#inline-diff)
 * [Emoji](#emoji)
 * [Special GitLab references](#special-gitlab-references)
-* [Task lists](#task-lists)
+* [Task Lists](#task-lists)
 
 **[Standard Markdown](#standard-markdown)**
 
@@ -89,6 +90,37 @@ GFM will autolink almost any URL you copy and paste into your text.
 * irc://irc.freenode.net/gitlab
 * http://localhost:3000
 
+## Multiline Blockquote
+
+On top of standard Markdown [blockquotes](#blockquotes), which require prepending `>` to quoted lines,
+GFM supports multiline blockquotes fenced by <code>>>></code>.
+
+```no-highlight
+>>>
+If you paste a message from somewhere else
+
+that
+
+spans
+
+multiple lines,
+
+you can quote that without having to manually prepend `>` to every line!
+>>>
+```
+
+>>>
+If you paste a message from somewhere else
+
+that
+
+spans
+
+multiple lines,
+
+you can quote that without having to manually prepend `>` to every line!
+>>>
+
 ## Code and Syntax Highlighting
 
 _GitLab uses the [Rouge Ruby library][rouge] for syntax highlighting. For a
diff --git a/lib/banzai/filter/blockquote_fence_filter.rb b/lib/banzai/filter/blockquote_fence_filter.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d2c4b1e4d76914254d1ca6b8cd8e89269a06aaa5
--- /dev/null
+++ b/lib/banzai/filter/blockquote_fence_filter.rb
@@ -0,0 +1,71 @@
+module Banzai
+  module Filter
+    class BlockquoteFenceFilter < HTML::Pipeline::TextFilter
+      REGEX = %r{
+          (?<code>
+            # Code blocks:
+            # ```
+            # Anything, including `>>>` blocks which are ignored by this filter
+            # ```
+
+            ^```
+            .+?
+            \n```$
+          )
+        |
+          (?<html>
+            # HTML block:
+            # <tag>
+            # Anything, including `>>>` blocks which are ignored by this filter
+            # </tag>
+
+            ^<[^>]+?>\n
+            .+?
+            \n<\/[^>]+?>$
+          )
+        |
+          (?:
+            # Blockquote:
+            # >>>
+            # Anything, including code and HTML blocks
+            # >>>
+
+            ^>>>\n
+            (?<quote>
+              (?:
+                  # Any character that doesn't introduce a code or HTML block
+                  (?!
+                      ^```
+                    |
+                      ^<[^>]+?>\n
+                  )
+                  .
+                |
+                  # A code block
+                  \g<code>
+                |
+                  # An HTML block
+                  \g<html>
+              )+?
+            )
+            \n>>>$
+          )
+      }mx.freeze
+
+      def initialize(text, context = nil, result = nil)
+        super text, context, result
+        @text = @text.delete("\r")
+      end
+
+      def call
+        @text.gsub(REGEX) do
+          if $~[:quote]
+            $~[:quote].gsub(/^/, "> ").gsub(/^> $/, ">")
+          else
+            $~[0]
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/banzai/pipeline/pre_process_pipeline.rb b/lib/banzai/pipeline/pre_process_pipeline.rb
index 50dc978b452be25ff29e5178aa153a2e31e7ae76..6cf219661d3f33f8400d44e48a63b8105aee8ecb 100644
--- a/lib/banzai/pipeline/pre_process_pipeline.rb
+++ b/lib/banzai/pipeline/pre_process_pipeline.rb
@@ -3,7 +3,8 @@ module Banzai
     class PreProcessPipeline < BasePipeline
       def self.filters
         FilterArray[
-          Filter::YamlFrontMatterFilter
+          Filter::YamlFrontMatterFilter,
+          Filter::BlockquoteFenceFilter,
         ]
       end
 
diff --git a/spec/fixtures/blockquote_fence_after.md b/spec/fixtures/blockquote_fence_after.md
new file mode 100644
index 0000000000000000000000000000000000000000..2652a842c0e343555553cccb70eb69a01708c73f
--- /dev/null
+++ b/spec/fixtures/blockquote_fence_after.md
@@ -0,0 +1,115 @@
+Single `>>>` inside code block:
+
+```
+# Code
+>>>
+# Code
+```
+
+Double `>>>` inside code block:
+
+```txt
+# Code
+>>>
+# Code
+>>>
+# Code
+```
+
+Blockquote outside code block:
+
+> Quote
+
+Code block inside blockquote:
+
+> Quote
+>
+> ```
+> # Code
+> ```
+>
+> Quote
+
+Single `>>>` inside code block inside blockquote:
+
+> Quote
+>
+> ```
+> # Code
+> >>>
+> # Code
+> ```
+>
+> Quote
+
+Double `>>>` inside code block inside blockquote:
+
+> Quote
+>
+> ```
+> # Code
+> >>>
+> # Code
+> >>>
+> # Code
+> ```
+>
+> Quote
+
+Single `>>>` inside HTML:
+
+<pre>
+# Code
+>>>
+# Code
+</pre>
+
+Double `>>>` inside HTML:
+
+<pre>
+# Code
+>>>
+# Code
+>>>
+# Code
+</pre>
+
+Blockquote outside HTML:
+
+> Quote
+
+HTML inside blockquote:
+
+> Quote
+>
+> <pre>
+> # Code
+> </pre>
+>
+> Quote
+
+Single `>>>` inside HTML inside blockquote:
+
+> Quote
+>
+> <pre>
+> # Code
+> >>>
+> # Code
+> </pre>
+>
+> Quote
+
+Double `>>>` inside HTML inside blockquote:
+
+> Quote
+>
+> <pre>
+> # Code
+> >>>
+> # Code
+> >>>
+> # Code
+> </pre>
+>
+> Quote
diff --git a/spec/fixtures/blockquote_fence_before.md b/spec/fixtures/blockquote_fence_before.md
new file mode 100644
index 0000000000000000000000000000000000000000..d52eec7289625137d670a546128cb9084f4abfdd
--- /dev/null
+++ b/spec/fixtures/blockquote_fence_before.md
@@ -0,0 +1,131 @@
+Single `>>>` inside code block:
+
+```
+# Code
+>>>
+# Code
+```
+
+Double `>>>` inside code block:
+
+```txt
+# Code
+>>>
+# Code
+>>>
+# Code
+```
+
+Blockquote outside code block:
+
+>>>
+Quote
+>>>
+
+Code block inside blockquote:
+
+>>>
+Quote
+
+```
+# Code
+```
+
+Quote
+>>>
+
+Single `>>>` inside code block inside blockquote:
+
+>>>
+Quote
+
+```
+# Code
+>>>
+# Code
+```
+
+Quote
+>>>
+
+Double `>>>` inside code block inside blockquote:
+
+>>>
+Quote
+
+```
+# Code
+>>>
+# Code
+>>>
+# Code
+```
+
+Quote
+>>>
+
+Single `>>>` inside HTML:
+
+<pre>
+# Code
+>>>
+# Code
+</pre>
+
+Double `>>>` inside HTML:
+
+<pre>
+# Code
+>>>
+# Code
+>>>
+# Code
+</pre>
+
+Blockquote outside HTML:
+
+>>>
+Quote
+>>>
+
+HTML inside blockquote:
+
+>>>
+Quote
+
+<pre>
+# Code
+</pre>
+
+Quote
+>>>
+
+Single `>>>` inside HTML inside blockquote:
+
+>>>
+Quote
+
+<pre>
+# Code
+>>>
+# Code
+</pre>
+
+Quote
+>>>
+
+Double `>>>` inside HTML inside blockquote:
+
+>>>
+Quote
+
+<pre>
+# Code
+>>>
+# Code
+>>>
+# Code
+</pre>
+
+Quote
+>>>
diff --git a/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb b/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2799249ae3e4b0024f2fa5b284073f9e28cae6b2
--- /dev/null
+++ b/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb
@@ -0,0 +1,14 @@
+require 'rails_helper'
+
+describe Banzai::Filter::BlockquoteFenceFilter, lib: true do
+  include FilterSpecHelper
+
+  it 'converts blockquote fences to blockquote lines' do
+    content = File.read(Rails.root.join('spec/fixtures/blockquote_fence_before.md'))
+    expected = File.read(Rails.root.join('spec/fixtures/blockquote_fence_after.md'))
+
+    output = filter(content)
+
+    expect(output).to eq(expected)
+  end
+end