diff --git a/lib/gitlab/markdown/autolink_filter.rb b/lib/gitlab/markdown/autolink_filter.rb
index 4e14a048cfb3dc96e3cb9c4ca7024b1347499de3..541f1d88ffc356f86cfb9ae97e77d007833ff6bb 100644
--- a/lib/gitlab/markdown/autolink_filter.rb
+++ b/lib/gitlab/markdown/autolink_filter.rb
@@ -87,8 +87,14 @@ module Gitlab
 
       def autolink_filter(text)
         text.gsub(LINK_PATTERN) do |match|
+          # Remove any trailing HTML entities and store them for appending
+          # outside the link element. The entity must be marked HTML safe in
+          # order to be output literally rather than escaped.
+          match.gsub!(/((?:&[\w#]+;)+)\z/, '')
+          dropped = ($1 || '').html_safe
+
           options = link_options.merge(href: match)
-          content_tag(:a, match, options)
+          content_tag(:a, match, options) + dropped
         end
       end
 
diff --git a/spec/lib/gitlab/markdown/autolink_filter_spec.rb b/spec/lib/gitlab/markdown/autolink_filter_spec.rb
index 982be0782c93953dac9d5578fc250856494c9836..26332ba5217f38f18d1639557bb03fccfdb1eef0 100644
--- a/spec/lib/gitlab/markdown/autolink_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/autolink_filter_spec.rb
@@ -86,6 +86,16 @@ module Gitlab::Markdown
 
         doc = filter("See #{link}, ok?")
         expect(doc.at_css('a').text).to eq link
+
+        doc = filter("See #{link}...")
+        expect(doc.at_css('a').text).to eq link
+      end
+
+      it 'does not include trailing HTML entities' do
+        doc = filter("See <<<#{link}>>>")
+
+        expect(doc.at_css('a')['href']).to eq link
+        expect(doc.text).to eq "See <<<#{link}>>>"
       end
 
       it 'accepts link_attr options' do