diff --git a/Gemfile b/Gemfile
index cfc205fd8665df3aebc4d7472f41f6b99d0da512..e5acee58adff0b882c5d17b6b3fac3142bc30cbd 100644
--- a/Gemfile
+++ b/Gemfile
@@ -79,6 +79,9 @@ gem "six"
 # Seed data
 gem "seed-fu"
 
+# Markup pipeline for GitLab
+gem 'html-pipeline-gitlab', '~> 0.1.0'
+
 # Markdown to HTML
 gem "github-markup"
 
@@ -157,7 +160,7 @@ gem "rack-attack"
 # Ace editor
 gem 'ace-rails-ap'
 
-# Keyboard shortcuts 
+# Keyboard shortcuts
 gem 'mousetrap-rails'
 
 # Semantic UI Sass for Sidebar
diff --git a/Gemfile.lock b/Gemfile.lock
index bd7ebf3ef4416065e9957a8cda13e15677ec5036..a2660342ac6de763282ff6c77f45f7214cce3663 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -239,6 +239,12 @@ GEM
     hipchat (0.14.0)
       httparty
       httparty
+    html-pipeline (1.11.0)
+      activesupport (>= 2)
+      nokogiri (~> 1.4)
+    html-pipeline-gitlab (0.1.0)
+      gitlab_emoji (~> 0.0.1.1)
+      html-pipeline (~> 1.11.0)
     http_parser.rb (0.5.3)
     httparty (0.13.0)
       json (~> 1.8)
@@ -629,6 +635,7 @@ DEPENDENCIES
   guard-spinach
   haml-rails
   hipchat (~> 0.14.0)
+  html-pipeline-gitlab (~> 0.1.0)
   httparty
   jasmine (= 2.0.2)
   jquery-atwho-rails (~> 0.3.3)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 07938b8065d819f9a2e5dad92ea503ae4bedb4aa..728c5041074193f8cf81c90d04fea699e9dbd288 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -151,12 +151,6 @@ def simple_sanitize(str)
     sanitize(str, tags: %w(a span))
   end
 
-  def image_url(source)
-    # prevent relative_root_path being added twice (it's part of root_url and path_to_image)
-    root_url.sub(/#{root_path}$/, path_to_image(source))
-  end
-
-  alias_method :url_to_image, :image_url
 
   def body_data_page
     path = controller.controller_path.split('/')
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index 6017a4c86c11d17e550535fef7724585e46301c9..d346acf0d321d8c9a1dba685cd2e18bbff2211a3 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -1,3 +1,6 @@
+require 'html/pipeline'
+require 'html/pipeline/gitlab'
+
 module Gitlab
   # Custom parser for GitLab-flavored Markdown
   #
@@ -62,6 +65,16 @@ def gfm(text, project = @project, html_options = {})
         insert_piece($1)
       end
 
+      # Context passed to the markdoqwn pipeline
+      markdown_context = {
+        asset_root: File.join(root_url,
+                              Gitlab::Application.config.assets.prefix)
+      }
+
+      result = HTML::Pipeline::Gitlab::MarkdownPipeline.call(text,
+                                                             markdown_context)
+      text = result[:output].to_html(save_with: 0)
+
       allowed_attributes = ActionView::Base.sanitized_allowed_attributes
       allowed_tags = ActionView::Base.sanitized_allowed_tags
 
@@ -91,7 +104,6 @@ def insert_piece(id)
     # Returns parsed text
     def parse(text, project = @project)
       parse_references(text, project) if project
-      parse_emoji(text)
 
       text
     end
@@ -136,28 +148,6 @@ def parse_references(text, project = @project)
       end
     end
 
-    EMOJI_PATTERN = %r{(:(\S+):)}.freeze
-
-    def parse_emoji(text)
-      # parse emoji
-      text.gsub!(EMOJI_PATTERN) do |match|
-        if valid_emoji?($2)
-          image_tag(url_to_image("emoji/#{$2}.png"), class: 'emoji', title: $1, alt: $1, size: "20x20")
-        else
-          match
-        end
-      end
-    end
-
-    # Private: Checks if an emoji icon exists in the image asset directory
-    #
-    # emoji - Identifier of the emoji as a string (e.g., "+1", "heart")
-    #
-    # Returns boolean
-    def valid_emoji?(emoji)
-      Emoji.find_by_name(emoji)
-    end
-
     # Private: Dispatches to a dedicated processing method based on reference
     #
     # reference  - Object reference ("@1234", "!567", etc.)
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index 46337f8bafdc8311eb4d88b0526a7fee0d7b81e8..6c865b1e079eb5712efdeb42437e2959d16ac422 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -14,6 +14,10 @@
   let(:snippet)       { create(:project_snippet, project: project) }
   let(:member)        { project.project_members.where(user_id: user).first }
 
+  def url_helper(image_name)
+    File.join(root_url, 'assets', image_name)
+  end
+
   before do
     # Helper expects a @project instance variable
     @project = project
@@ -38,8 +42,8 @@
 
     it "should not touch HTML entities" do
       @project.issues.stub(:where).with(id: '39').and_return([issue])
-      actual = expected = "We'll accept good pull requests."
-      gfm(actual).should == expected
+      actual = 'We'll accept good pull requests.'
+      gfm(actual).should == "We'll accept good pull requests."
     end
 
     it "should forward HTML options to links" do
@@ -330,7 +334,8 @@
       end
 
       it "keeps whitespace intact" do
-        gfm("This deserves a :+1: big time.").should match(/deserves a <img.+\/> big time/)
+        gfm('This deserves a :+1: big time.').
+          should match(/deserves a <img.+> big time/)
       end
 
       it "ignores invalid emoji" do
@@ -448,7 +453,8 @@
     end
 
     it "should leave inline code untouched" do
-      markdown("\nDon't use `$#{snippet.id}` here.\n").should == "<p>Don&#39;t use <code>$#{snippet.id}</code> here.</p>\n"
+      markdown("\nDon't use `$#{snippet.id}` here.\n").should ==
+        "<p>Don't use <code>$#{snippet.id}</code> here.</p>\n"
     end
 
     it "should leave ref-like autolinks untouched" do
@@ -468,7 +474,7 @@
     end
 
     it "should generate absolute urls for emoji" do
-      markdown(":smile:").should include("src=\"#{url_to_image("emoji/smile")}")
+      markdown(":smile:").should include("src=\"#{url_helper('emoji/smile')}")
     end
 
     it "should handle relative urls for a file in master" do