diff --git a/lib/gitlab/markdown/abstract_reference_filter.rb b/lib/gitlab/markdown/abstract_reference_filter.rb
index b044a73ed179e3971873971313a611543ab8e311..0ec55c0207e136f4a301dc8365249968597e51e9 100644
--- a/lib/gitlab/markdown/abstract_reference_filter.rb
+++ b/lib/gitlab/markdown/abstract_reference_filter.rb
@@ -60,17 +60,27 @@ module Gitlab
       end
 
       def call
+        # `#123`
         replace_text_nodes_matching(object_class.reference_pattern) do |content|
           object_link_filter(content, object_class.reference_pattern)
         end
 
+        # `[Issue](#123)`, which is turned into
+        # `<a href="#123">Issue</a>`
         replace_link_nodes_with_href(object_class.reference_pattern) do |link, text|
           object_link_filter(link, object_class.reference_pattern, link_text: text)
         end
 
+        # `http://gitlab.example.com/namespace/project/issues/123`, which is turned into
+        # `<a href="http://gitlab.example.com/namespace/project/issues/123">http://gitlab.example.com/namespace/project/issues/123</a>`
         replace_link_nodes_with_text(object_class.link_reference_pattern) do |text|
           object_link_filter(text, object_class.link_reference_pattern)
         end
+
+        # `[Issue](http://gitlab.example.com/namespace/project/issues/123)`, which is turned into
+        # `<a href="http://gitlab.example.com/namespace/project/issues/123">Issue</a>`
+        replace_link_nodes_with_href(object_class.link_reference_pattern) do |link, text|
+          object_link_filter(link, object_class.link_reference_pattern, link_text: text)
         end
       end
 
@@ -88,7 +98,12 @@ module Gitlab
           if project && object = find_object(project, id)
             title = escape_once(object_link_title(object))
             klass = reference_class(object_sym)
-            data  = data_attribute(project: project.id, object_sym => object.id, original: match)
+            
+            data  = data_attribute(
+              original:     link_text || match,
+              project:      project.id,
+              object_sym => object.id
+            )
 
             url = matches[:url] if matches.names.include?("url")
             url ||= url_for_object(object, project)
diff --git a/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb b/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
index 92158382790a31de58b97ab0f0b61a51b703d342..9ce63f9af464e18f10e155e5903ada0c409397cc 100644
--- a/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
@@ -143,7 +143,7 @@ module Gitlab::Markdown
       end
     end
 
-    context 'URL cross-project reference' do
+    context 'cross-project URL reference' do
       let(:namespace) { create(:namespace, name: 'cross-reference') }
       let(:project2)  { create(:project, :public, namespace: namespace) }
       let(:range)  { CommitRange.new("#{commit1.id}...master", project) }
diff --git a/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb b/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
index 6fe9b165ff575ac31c7ddb07488007eada5c3a78..78a3603269cf7c2ae22fa8f5799528c250a6c869 100644
--- a/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
@@ -132,7 +132,7 @@ module Gitlab::Markdown
       end
     end
 
-    context 'URL cross-project reference' do
+    context 'cross-project URL reference' do
       let(:namespace) { create(:namespace, name: 'cross-reference') }
       let(:project2)  { create(:project, :public, namespace: namespace) }
       let(:commit)    { project2.commit }
diff --git a/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb b/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
index 0a741688b82875d312ef46e517f908086fc15f7b..078ff3ed4b2de9c43050d00c4b0b34ddded492aa 100644
--- a/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
@@ -136,30 +136,70 @@ module Gitlab::Markdown
       end
     end
 
-    context 'URL cross-project reference' do
+    context 'cross-project URL reference' do
       let(:namespace) { create(:namespace, name: 'cross-reference') }
       let(:project2)  { create(:empty_project, :public, namespace: namespace) }
       let(:issue)     { create(:issue, project: project2) }
       let(:reference) { helper.url_for_issue(issue.iid, project2) + "#note_123" }
 
-      it 'ignores valid references when cross-reference project uses external tracker' do
-        expect_any_instance_of(Project).to receive(:get_issue).
-          with(issue.iid).and_return(nil)
+      it 'links to a valid reference' do
+        doc = reference_filter("See #{reference}")
 
-        exp = act = "Issue #{reference}"
-        expect(reference_filter(act).to_html).to match(/<a.+>#{Regexp.escape(reference)}<\/a>/)
+        expect(doc.css('a').first.attr('href')).
+          to eq reference
+      end
+
+      it 'links with adjacent text' do
+        doc = reference_filter("Fixed (#{reference}.)")
+        expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(issue.to_reference(project))} \(comment 123\)<\/a>\.\)/)
+      end
+
+      it 'adds to the results hash' do
+        result = reference_pipeline_result("Fixed #{reference}")
+        expect(result[:references][:issue]).to eq [issue]
+      end
+    end
+
+    context 'cross-project reference in link href' do
+      let(:namespace) { create(:namespace, name: 'cross-reference') }
+      let(:project2)  { create(:empty_project, :public, namespace: namespace) }
+      let(:issue)     { create(:issue, project: project2) }
+      let(:reference) { %Q{<a href="#{issue.to_reference(project)}">Reference</a>} }
+
+      it 'links to a valid reference' do
+        doc = reference_filter("See #{reference}")
+
+        expect(doc.css('a').first.attr('href')).
+          to eq helper.url_for_issue(issue.iid, project2)
+      end
+
+      it 'links with adjacent text' do
+        doc = reference_filter("Fixed (#{reference}.)")
+        expect(doc.to_html).to match(/\(<a.+>Reference<\/a>\.\)/)
       end
 
+      it 'adds to the results hash' do
+        result = reference_pipeline_result("Fixed #{reference}")
+        expect(result[:references][:issue]).to eq [issue]
+      end
+    end
+
+    context 'cross-project URL in link href' do
+      let(:namespace) { create(:namespace, name: 'cross-reference') }
+      let(:project2)  { create(:empty_project, :public, namespace: namespace) }
+      let(:issue)     { create(:issue, project: project2) }
+      let(:reference) { %Q{<a href="#{helper.url_for_issue(issue.iid, project2) + "#note_123"}">Reference</a>} }
+
       it 'links to a valid reference' do
         doc = reference_filter("See #{reference}")
 
         expect(doc.css('a').first.attr('href')).
-          to eq reference
+          to eq helper.url_for_issue(issue.iid, project2) + "#note_123"
       end
 
       it 'links with adjacent text' do
         doc = reference_filter("Fixed (#{reference}.)")
-        expect(doc.to_html).to match(/\(<a.+>#{Regexp.escape(issue.to_reference(project))} \(comment 123\)<\/a>\.\)/)
+        expect(doc.to_html).to match(/\(<a.+>Reference<\/a>\.\)/)
       end
 
       it 'adds to the results hash' do
diff --git a/spec/lib/gitlab/markdown/label_reference_filter_spec.rb b/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
index fc21b65a8437106d35f54ac484d0f4bdbda86cf8..ef6dd524aba51efbb71c3243eed03ff527d1376a 100644
--- a/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
@@ -16,17 +16,17 @@ module Gitlab::Markdown
     %w(pre code a style).each do |elem|
       it "ignores valid references contained inside '#{elem}' element" do
         exp = act = "<#{elem}>Label #{reference}</#{elem}>"
-        expect(filter(act).to_html).to eq exp
+        expect(reference_filter(act).to_html).to eq exp
       end
     end
 
     it 'includes default classes' do
-      doc = filter("Label #{reference}")
+      doc = reference_filter("Label #{reference}")
       expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-label'
     end
 
     it 'includes a data-project attribute' do
-      doc = filter("Label #{reference}")
+      doc = reference_filter("Label #{reference}")
       link = doc.css('a').first
 
       expect(link).to have_attribute('data-project')
@@ -34,7 +34,7 @@ module Gitlab::Markdown
     end
 
     it 'includes a data-label attribute' do
-      doc = filter("See #{reference}")
+      doc = reference_filter("See #{reference}")
       link = doc.css('a').first
 
       expect(link).to have_attribute('data-label')
@@ -42,7 +42,7 @@ module Gitlab::Markdown
     end
 
     it 'supports an :only_path context' do
-      doc = filter("Label #{reference}", only_path: true)
+      doc = reference_filter("Label #{reference}", only_path: true)
       link = doc.css('a').first.attr('href')
 
       expect(link).not_to match %r(https?://)
@@ -56,33 +56,33 @@ module Gitlab::Markdown
 
     describe 'label span element' do
       it 'includes default classes' do
-        doc = filter("Label #{reference}")
+        doc = reference_filter("Label #{reference}")
         expect(doc.css('a span').first.attr('class')).to eq 'label color-label'
       end
 
       it 'includes a style attribute' do
-        doc = filter("Label #{reference}")
+        doc = reference_filter("Label #{reference}")
         expect(doc.css('a span').first.attr('style')).to match(/\Abackground-color: #\h{6}; color: #\h{6}\z/)
       end
     end
 
     context 'Integer-based references' do
       it 'links to a valid reference' do
-        doc = filter("See #{reference}")
+        doc = reference_filter("See #{reference}")
 
         expect(doc.css('a').first.attr('href')).to eq urls.
           namespace_project_issues_url(project.namespace, project, label_name: label.name)
       end
 
       it 'links with adjacent text' do
-        doc = filter("Label (#{reference}.)")
+        doc = reference_filter("Label (#{reference}.)")
         expect(doc.to_html).to match(%r(\(<a.+><span.+>#{label.name}</span></a>\.\)))
       end
 
       it 'ignores invalid label IDs' do
         exp = act = "Label #{invalidate_reference(reference)}"
 
-        expect(filter(act).to_html).to eq exp
+        expect(reference_filter(act).to_html).to eq exp
       end
     end
 
@@ -91,7 +91,7 @@ module Gitlab::Markdown
       let(:reference) { "#{Label.reference_prefix}#{label.name}" }
 
       it 'links to a valid reference' do
-        doc = filter("See #{reference}")
+        doc = reference_filter("See #{reference}")
 
         expect(doc.css('a').first.attr('href')).to eq urls.
           namespace_project_issues_url(project.namespace, project, label_name: label.name)
@@ -99,14 +99,14 @@ module Gitlab::Markdown
       end
 
       it 'links with adjacent text' do
-        doc = filter("Label (#{reference}.)")
+        doc = reference_filter("Label (#{reference}.)")
         expect(doc.to_html).to match(%r(\(<a.+><span.+>#{label.name}</span></a>\.\)))
       end
 
       it 'ignores invalid label names' do
         exp = act = "Label #{Label.reference_prefix}#{label.name.reverse}"
 
-        expect(filter(act).to_html).to eq exp
+        expect(reference_filter(act).to_html).to eq exp
       end
     end
 
@@ -115,7 +115,7 @@ module Gitlab::Markdown
       let(:reference) { label.to_reference(:name) }
 
       it 'links to a valid reference' do
-        doc = filter("See #{reference}")
+        doc = reference_filter("See #{reference}")
 
         expect(doc.css('a').first.attr('href')).to eq urls.
           namespace_project_issues_url(project.namespace, project, label_name: label.name)
@@ -123,21 +123,58 @@ module Gitlab::Markdown
       end
 
       it 'links with adjacent text' do
-        doc = filter("Label (#{reference}.)")
+        doc = reference_filter("Label (#{reference}.)")
         expect(doc.to_html).to match(%r(\(<a.+><span.+>#{label.name}</span></a>\.\)))
       end
 
       it 'ignores invalid label names' do
         exp = act = %(Label #{Label.reference_prefix}"#{label.name.reverse}")
 
-        expect(filter(act).to_html).to eq exp
+        expect(reference_filter(act).to_html).to eq exp
       end
     end
 
     describe 'edge cases' do
       it 'gracefully handles non-references matching the pattern' do
         exp = act = '(format nil "~0f" 3.0) ; 3.0'
-        expect(filter(act).to_html).to eq exp
+        expect(reference_filter(act).to_html).to eq exp
+      end
+    end
+
+    describe 'referencing a label in a link href' do
+      let(:reference) { %Q{<a href="#{label.to_reference}">Label</a>} }
+
+      it 'links to a valid reference' do
+        doc = reference_filter("See #{reference}")
+
+        expect(doc.css('a').first.attr('href')).to eq urls.
+          namespace_project_issues_url(project.namespace, project, label_name: label.name)
+      end
+
+      it 'links with adjacent text' do
+        doc = reference_filter("Label (#{reference}.)")
+        expect(doc.to_html).to match(%r(\(<a.+>Label</a>\.\)))
+      end
+
+      it 'includes a data-project attribute' do
+        doc = reference_filter("Label #{reference}")
+        link = doc.css('a').first
+
+        expect(link).to have_attribute('data-project')
+        expect(link.attr('data-project')).to eq project.id.to_s
+      end
+
+      it 'includes a data-label attribute' do
+        doc = reference_filter("See #{reference}")
+        link = doc.css('a').first
+
+        expect(link).to have_attribute('data-label')
+        expect(link.attr('data-label')).to eq label.id.to_s
+      end
+
+      it 'adds to the results hash' do
+        result = reference_pipeline_result("Label #{reference}")
+        expect(result[:references][:label]).to eq [label]
       end
     end
   end
diff --git a/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb b/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
index cdb3390e793b456637656758cc76d6ff5b1f6292..4a23205112714e719f9806144dcf0e1500cbe7a9 100644
--- a/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
@@ -117,7 +117,7 @@ module Gitlab::Markdown
       end
     end
 
-    context 'URL cross-project reference' do
+    context 'cross-project URL reference' do
       let(:namespace) { create(:namespace, name: 'cross-reference') }
       let(:project2)  { create(:project, :public, namespace: namespace) }
       let(:merge)     { create(:merge_request, source_project: project2, target_project: project2) }
diff --git a/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb b/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
index 73d20957a563db66b7e0f04a3066602e581cd723..b6f05710c3b659fbc8433ca8a2993e97512d0aac 100644
--- a/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
@@ -115,7 +115,7 @@ module Gitlab::Markdown
       end
     end
 
-    context 'URL cross-project reference' do
+    context 'cross-project URL reference' do
       let(:namespace) { create(:namespace, name: 'cross-reference') }
       let(:project2)  { create(:empty_project, :public, namespace: namespace) }
       let(:snippet)   { create(:project_snippet, project: project2) }
diff --git a/spec/lib/gitlab/markdown/user_reference_filter_spec.rb b/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
index d9e0d7c42db7fd1bc83981d4b5bdeb0600596fbd..25379f0670ef198bde870d35d9d8aacc3c307bca 100644
--- a/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
@@ -14,13 +14,13 @@ module Gitlab::Markdown
 
     it 'ignores invalid users' do
       exp = act = "Hey #{invalidate_reference(reference)}"
-      expect(filter(act).to_html).to eq(exp)
+      expect(reference_filter(act).to_html).to eq(exp)
     end
 
     %w(pre code a style).each do |elem|
       it "ignores valid references contained inside '#{elem}' element" do
         exp = act = "<#{elem}>Hey #{reference}</#{elem}>"
-        expect(filter(act).to_html).to eq exp
+        expect(reference_filter(act).to_html).to eq exp
       end
     end
 
@@ -32,7 +32,7 @@ module Gitlab::Markdown
       end
 
       it 'supports a special @all mention' do
-        doc = filter("Hey #{reference}")
+        doc = reference_filter("Hey #{reference}")
         expect(doc.css('a').length).to eq 1
         expect(doc.css('a').first.attr('href'))
           .to eq urls.namespace_project_url(project.namespace, project)
@@ -46,26 +46,26 @@ module Gitlab::Markdown
 
     context 'mentioning a user' do
       it 'links to a User' do
-        doc = filter("Hey #{reference}")
+        doc = reference_filter("Hey #{reference}")
         expect(doc.css('a').first.attr('href')).to eq urls.user_url(user)
       end
 
       it 'links to a User with a period' do
         user = create(:user, name: 'alphA.Beta')
 
-        doc = filter("Hey #{user.to_reference}")
+        doc = reference_filter("Hey #{user.to_reference}")
         expect(doc.css('a').length).to eq 1
       end
 
       it 'links to a User with an underscore' do
         user = create(:user, name: 'ping_pong_king')
 
-        doc = filter("Hey #{user.to_reference}")
+        doc = reference_filter("Hey #{user.to_reference}")
         expect(doc.css('a').length).to eq 1
       end
 
       it 'includes a data-user attribute' do
-        doc = filter("Hey #{reference}")
+        doc = reference_filter("Hey #{reference}")
         link = doc.css('a').first
 
         expect(link).to have_attribute('data-user')
@@ -83,12 +83,12 @@ module Gitlab::Markdown
       let(:reference) { group.to_reference }
 
       it 'links to the Group' do
-        doc = filter("Hey #{reference}")
+        doc = reference_filter("Hey #{reference}")
         expect(doc.css('a').first.attr('href')).to eq urls.group_url(group)
       end
 
       it 'includes a data-group attribute' do
-        doc = filter("Hey #{reference}")
+        doc = reference_filter("Hey #{reference}")
         link = doc.css('a').first
 
         expect(link).to have_attribute('data-group')
@@ -102,21 +102,48 @@ module Gitlab::Markdown
     end
 
     it 'links with adjacent text' do
-      doc = filter("Mention me (#{reference}.)")
+      doc = reference_filter("Mention me (#{reference}.)")
       expect(doc.to_html).to match(/\(<a.+>#{reference}<\/a>\.\)/)
     end
 
     it 'includes default classes' do
-      doc = filter("Hey #{reference}")
+      doc = reference_filter("Hey #{reference}")
       expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-project_member'
     end
 
     it 'supports an :only_path context' do
-      doc = filter("Hey #{reference}", only_path: true)
+      doc = reference_filter("Hey #{reference}", only_path: true)
       link = doc.css('a').first.attr('href')
 
       expect(link).not_to match %r(https?://)
       expect(link).to eq urls.user_path(user)
     end
+
+    context 'referencing a user in a link href' do
+      let(:reference) { %Q{<a href="#{user.to_reference}">User</a>} }
+
+      it 'links to a User' do
+        doc = reference_filter("Hey #{reference}")
+        expect(doc.css('a').first.attr('href')).to eq urls.user_url(user)
+      end
+
+      it 'links with adjacent text' do
+        doc = reference_filter("Mention me (#{reference}.)")
+        expect(doc.to_html).to match(/\(<a.+>User<\/a>\.\)/)
+      end
+
+      it 'includes a data-user attribute' do
+        doc = reference_filter("Hey #{reference}")
+        link = doc.css('a').first
+
+        expect(link).to have_attribute('data-user')
+        expect(link.attr('data-user')).to eq user.namespace.owner_id.to_s
+      end
+
+      it 'adds to the results hash' do
+        result = reference_pipeline_result("Hey #{reference}")
+        expect(result[:references][:user]).to eq [user]
+      end
+    end
   end
 end