diff --git a/app/assets/javascripts/lib/notify.js.coffee b/app/assets/javascripts/lib/notify.js.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..3f9ca39912c05dce53bf17b5ad99f4001751289c
--- /dev/null
+++ b/app/assets/javascripts/lib/notify.js.coffee
@@ -0,0 +1,30 @@
+((w) ->
+  notificationGranted = (message, opts, onclick) ->
+    notification = new Notification(message, opts)
+
+    if onclick
+      notification.onclick = onclick
+
+  notifyPermissions = ->
+    if 'Notification' of window
+      Notification.requestPermission()
+
+  notifyMe = (message, body, icon, onclick) ->
+    opts =
+      body: body
+      icon: icon
+    # Let's check if the browser supports notifications
+    if !('Notification' of window)
+      # do nothing
+    else if Notification.permission == 'granted'
+      # If it's okay let's create a notification
+      notificationGranted message, opts, onclick
+    else if Notification.permission != 'denied'
+      Notification.requestPermission (permission) ->
+        # If the user accepts, let's create a notification
+        if permission == 'granted'
+          notificationGranted message, opts, onclick
+
+  w.notify = notifyMe
+  w.notifyPermissions = notifyPermissions
+) window
diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee
index 738ffc8343bfd34437915c56f7148ec2cbc8f5cc..7102a0673e9ea37a41c5b37ab21afcedaef31d86 100644
--- a/app/assets/javascripts/merge_request_widget.js.coffee
+++ b/app/assets/javascripts/merge_request_widget.js.coffee
@@ -2,13 +2,18 @@ class @MergeRequestWidget
   # Initialize MergeRequestWidget behavior
   #
   #   check_enable           - Boolean, whether to check automerge status
-  #   url_to_automerge_check - String, URL to use to check automerge status
-  #   current_status         - String, current automerge status
-  #   ci_enable              - Boolean, whether a CI service is enabled
-  #   url_to_ci_check        - String, URL to use to check CI status
+  #   merge_check_url - String, URL to use to check automerge status
+  #   ci_status_url        - String, URL to use to check CI status
   #
+
   constructor: (@opts) ->
-    modal = $('#modal_merge_info').modal(show: false)
+    $('#modal_merge_info').modal(show: false)
+    @firstCICheck = true
+    @readyForCICheck = true
+    clearInterval @fetchBuildStatusInterval
+
+    @pollCIStatus()
+    notifyPermissions()
 
   mergeInProgress: (deleteSourceBranch = false)->
     $.ajax
@@ -27,18 +32,57 @@ class @MergeRequestWidget
       dataType: 'json'
 
   getMergeStatus: ->
-    $.get @opts.url_to_automerge_check, (data) ->
+    $.get @opts.merge_check_url, (data) ->
       $('.mr-state-widget').replaceWith(data)
 
-  getCiStatus: ->
-    if @opts.ci_enable
-      $.get @opts.url_to_ci_check, (data) =>
-        this.showCiState data.status
+  ciLabelForStatus: (status) ->
+    if status == 'success'
+      'passed'
+    else
+      status
+
+  pollCIStatus: ->
+    @fetchBuildStatusInterval = setInterval ( =>
+      return if not @readyForCICheck
+
+      @getCIStatus(true)
+
+      @readyForCICheck = false
+    ), 5000
+
+  getCIStatus: (showNotification) ->
+    _this = @
+    $('.ci-widget-fetching').show()
+
+    $.getJSON @opts.ci_status_url, (data) =>
+      @readyForCICheck = true
+
+      if @firstCICheck
+        @firstCICheck = false
+        @opts.ci_status = data.status
+
+      if data.status isnt @opts.ci_status
+        @showCIStatus data.status
         if data.coverage
-          this.showCiCoverage data.coverage
-      , 'json'
+          @showCICoverage data.coverage
+
+        if showNotification
+          message = @opts.ci_message.replace('{{status}}', @ciLabelForStatus(data.status))
+          message = message.replace('{{sha}}', data.sha)
+          message = message.replace('{{title}}', data.title)
+
+          notify(
+            "Build #{@ciLabelForStatus(data.status)}",
+            message,
+            @opts.gitlab_icon,
+            ->
+              @close()
+              Turbolinks.visit _this.opts.builds_path
+          )
+
+        @opts.ci_status = data.status
 
-  showCiState: (state) ->
+  showCIStatus: (state) ->
     $('.ci_widget').hide()
     allowed_states = ["failed", "canceled", "running", "pending", "success", "skipped", "not_found"]
     if state in allowed_states
@@ -52,7 +96,7 @@ class @MergeRequestWidget
       $('.ci_widget.ci-error').show()
       @setMergeButtonClass('btn-danger')
 
-  showCiCoverage: (coverage) ->
+  showCICoverage: (coverage) ->
     text = 'Coverage ' + coverage + '%'
     $('.ci_widget:visible .ci-coverage').text(text)
 
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 62451ac73a9dd65f851795a144b190940ef77d6c..49064f5d50570f6c4d6463797fbb87ae8c15a734 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -224,14 +224,22 @@ def update_branches
   end
 
   def ci_status
-    ci_service = @merge_request.source_project.ci_service
-    status = ci_service.commit_status(merge_request.last_commit.sha, merge_request.source_branch)
+    ci_commit = @merge_request.ci_commit
+    if ci_commit
+      status = ci_commit.status
+      coverage = ci_commit.try(:coverage)
+    else
+      ci_service = @merge_request.source_project.ci_service
+      status = ci_service.commit_status(merge_request.last_commit.sha, merge_request.source_branch) if ci_service
 
-    if ci_service.respond_to?(:commit_coverage)
-      coverage = ci_service.commit_coverage(merge_request.last_commit.sha, merge_request.source_branch)
+      if ci_service.respond_to?(:commit_coverage)
+        coverage = ci_service.commit_coverage(merge_request.last_commit.sha, merge_request.source_branch)
+      end
     end
 
     response = {
+      title: merge_request.title,
+      sha: merge_request.last_commit_short_sha,
       status: status,
       coverage: coverage
     }
diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml
index b05ab8692156a0a8fce868d58b311d7537bd6912..2ec0d20a8796682d9bceeba128d7bd9dd1f27253 100644
--- a/app/views/projects/merge_requests/widget/_heading.html.haml
+++ b/app/views/projects/merge_requests/widget/_heading.html.haml
@@ -1,15 +1,17 @@
 - if @ci_commit
   .mr-widget-heading
-    .ci_widget{class: "ci-#{@ci_commit.status}"}
-      = ci_status_icon(@ci_commit)
-      %span
-        Build
-        = ci_status_label(@ci_commit)
-      for
-      = succeed "." do
-        = link_to @ci_commit.short_sha, namespace_project_commit_path(@merge_request.source_project.namespace, @merge_request.source_project, @ci_commit.sha), class: "monospace"
-      %span.ci-coverage
-      = link_to "View details", builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "js-show-tab", data: {action: 'builds'}
+    - %w[success skipped canceled failed running pending].each do |status|
+      .ci_widget{ class: "ci-#{status}", style: ("display:none" unless @ci_commit.status == status) }
+        = ci_icon_for_status(status)
+        %span
+          CI build
+          = ci_label_for_status(status)
+        for
+        - commit = @merge_request.last_commit
+        = succeed "." do
+          = link_to @ci_commit.short_sha, namespace_project_commit_path(@merge_request.source_project.namespace, @merge_request.source_project, @ci_commit.sha), class: "monospace"
+        %span.ci-coverage
+        = link_to "View details", builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "js-show-tab", data: {action: 'builds'}
 
 - elsif @merge_request.has_ci?
   - # Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX
@@ -43,5 +45,5 @@
 
   :javascript
     $(function() {
-      merge_request_widget.getCiStatus();
+      merge_request_widget.getCIStatus(false);
     });
diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml
index a489d4f9b24ee4e675a9ce4e3299408e0816c20f..2be06aebe6c3fe21a645d32ad85221f3270f6865 100644
--- a/app/views/projects/merge_requests/widget/_show.html.haml
+++ b/app/views/projects/merge_requests/widget/_show.html.haml
@@ -9,12 +9,17 @@
 
 :javascript
   var merge_request_widget;
-
-  merge_request_widget = new MergeRequestWidget({
-    url_to_automerge_check: "#{merge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
+  var opts = {
+    merge_check_url: "#{merge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
     check_enable: #{@merge_request.unchecked? ? "true" : "false"},
-    url_to_ci_check: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
+    ci_status_url: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
+    gitlab_icon: "#{asset_path 'gitlab_logo.png'}",
+    ci_status: "",
+    ci_message: "Build {{status}} for \"{{title}}\"",
     ci_enable: #{@project.ci_service ? "true" : "false"},
-    current_status: "#{@merge_request.gitlab_merge_status}",
-  });
+    builds_path: "#{builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}"
+  };
 
+  if(typeof merge_request_widget === 'undefined') {
+    merge_request_widget = new MergeRequestWidget(opts);
+  }