diff --git a/app/controllers/admin/hooks_controller.rb b/app/controllers/admin/hooks_controller.rb
index a119934febcf4d96dddd46adc7c1e147f2d141e2..ccfe553c89e0ed164a175f46913922e86e7a3b9d 100644
--- a/app/controllers/admin/hooks_controller.rb
+++ b/app/controllers/admin/hooks_controller.rb
@@ -60,6 +60,7 @@ class Admin::HooksController < Admin::ApplicationController
       :enable_ssl_verification,
       :push_events,
       :tag_push_events,
+      :repository_update_events,
       :token,
       :url
     )
diff --git a/app/models/hooks/system_hook.rb b/app/models/hooks/system_hook.rb
index 777bad1e724166f6a8558f332cecee5373863c14..c645805c6dab13eef742a7d55830e8aa55c9efcb 100644
--- a/app/models/hooks/system_hook.rb
+++ b/app/models/hooks/system_hook.rb
@@ -1,4 +1,9 @@
 class SystemHook < WebHook
+  scope :repository_update_hooks, ->  { where(repository_update_events: true) }
+
+  default_value_for :push_events, false
+  default_value_for :repository_update_events, true
+
   def async_execute(data, hook_name)
     Sidekiq::Client.enqueue(SystemHookWorker, id, data, hook_name)
   end
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index 22a177ed36730b653cb70a5852519ad677e95ad1..7cf03aabd6f2c3ceaa53208d2b74c66224e3b884 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -10,6 +10,7 @@ class WebHook < ActiveRecord::Base
   default_value_for :tag_push_events, false
   default_value_for :build_events, false
   default_value_for :pipeline_events, false
+  default_value_for :repository_update_events, false
   default_value_for :enable_ssl_verification, true
 
   scope :push_hooks, -> { where(push_events: true) }
diff --git a/app/views/admin/hooks/_form.html.haml b/app/views/admin/hooks/_form.html.haml
index 6217d5fb1351b80988722a5bc0e89d1e19a5cdc4..645005c6deb21fdf5700ab4138e6221125e10ef1 100644
--- a/app/views/admin/hooks/_form.html.haml
+++ b/app/views/admin/hooks/_form.html.haml
@@ -18,19 +18,26 @@
       or adding ssh key. But you can also enable extra triggers like Push events.
 
     .prepend-top-default
+      = form.check_box :repository_update_events, class: 'pull-left'
+      .prepend-left-20
+        = form.label :repository_update_events, class: 'list-label' do
+          %strong Repository update events
+        %p.light
+          This URL will be triggered when repository is updated
+    %div
       = form.check_box :push_events, class: 'pull-left'
       .prepend-left-20
         = form.label :push_events, class: 'list-label' do
           %strong Push events
         %p.light
-          This url will be triggered by a push to the repository
+          This URL will be triggered for each branch updated to the repository
     %div
       = form.check_box :tag_push_events, class: 'pull-left'
       .prepend-left-20
         = form.label :tag_push_events, class: 'list-label' do
           %strong Tag push events
         %p.light
-          This url will be triggered when a new tag is pushed to the repository
+          This URL will be triggered when a new tag is pushed to the repository
 .form-group
   = form.label :enable_ssl_verification, 'SSL verification', class: 'control-label checkbox'
   .col-sm-10
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
index 71117758921228ea5537b740ed7d676450a1839e..3338b677bf56272d07c785282b5626777c40a5f1 100644
--- a/app/views/admin/hooks/index.html.haml
+++ b/app/views/admin/hooks/index.html.haml
@@ -27,7 +27,7 @@
             = link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: 'btn btn-remove btn-sm'
           .monospace= hook.url
           %div
-            - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger|
+            - %w(repository_update_events push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger|
               - if hook.send(trigger)
                 %span.label.label-gray= trigger.titleize
             %span.label.label-gray SSL Verification: #{hook.enable_ssl_verification ? 'enabled' : 'disabled'}
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 127d8dfbb61713636003b4d23544f9e0fd1468fc..c29571d3c62ab75770bde4a153298fac7e654071 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -20,13 +20,32 @@ class PostReceive
       # Nothing defined here yet.
     else
       process_project_changes(post_received)
+      process_repository_update(post_received)
     end
   end
 
-  def process_project_changes(post_received)
-    post_received.changes.each do |change|
-      oldrev, newrev, ref = change.strip.split(' ')
+  def process_repository_update(post_received)
+    changes = []
+    refs = Set.new
+
+    post_received.changes_refs do |oldrev, newrev, ref|
+      @user ||= post_received.identify(newrev)
 
+      unless @user
+        log("Triggered hook for non-existing user \"#{post_received.identifier}\"")
+        return false
+      end
+
+      changes << Gitlab::DataBuilder::Repository.single_change(oldrev, newrev, ref)
+      refs << ref
+    end
+
+    hook_data = Gitlab::DataBuilder::Repository.update(post_received.project, @user, changes, refs.to_a)
+    SystemHooksService.new.execute_hooks(hook_data, :repository_update_hooks)
+  end
+
+  def process_project_changes(post_received)
+    post_received.changes_refs do |oldrev, newrev, ref|
       @user ||= post_received.identify(newrev)
 
       unless @user
diff --git a/changelogs/unreleased/26325-system-hooks.yml b/changelogs/unreleased/26325-system-hooks.yml
new file mode 100644
index 0000000000000000000000000000000000000000..62b8adaeccd6a409532ab9dc5928554e8a4b729b
--- /dev/null
+++ b/changelogs/unreleased/26325-system-hooks.yml
@@ -0,0 +1,4 @@
+---
+title: 'Backported new SystemHook event: `repository_update`'
+merge_request: 11140
+author:
diff --git a/db/migrate/20170503023315_add_repository_update_events_to_web_hooks.rb b/db/migrate/20170503023315_add_repository_update_events_to_web_hooks.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0faea87a962e3483a8a2a3fdfabd54b056774996
--- /dev/null
+++ b/db/migrate/20170503023315_add_repository_update_events_to_web_hooks.rb
@@ -0,0 +1,15 @@
+class AddRepositoryUpdateEventsToWebHooks < ActiveRecord::Migration
+  include Gitlab::Database::MigrationHelpers
+
+  DOWNTIME = false
+
+  disable_ddl_transaction!
+
+  def up
+    add_column_with_default :web_hooks, :repository_update_events, :boolean, default: false, allow_null: false
+  end
+
+  def down
+    remove_column :web_hooks, :repository_update_events
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 60077ffd81212a3e4bb3b43acf82bda31ac80999..65eaccf766a887d16a6e2a0cbe747ea31f62bed8 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1404,6 +1404,7 @@ ActiveRecord::Schema.define(version: 20170508190732) do
     t.string "token"
     t.boolean "pipeline_events", default: false, null: false
     t.boolean "confidential_issues_events", default: false, null: false
+    t.boolean "repository_update_events", default: false, null: false
   end
 
   add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index ad5ffc8447377fb730329e18f3314413f9a3eab9..583ec5522fd0de6c1428527af2a953c57461a66e 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -266,7 +266,8 @@ X-Gitlab-Event: System Hook
 
 ## Push events
 
-Triggered when you push to the repository except when pushing tags.
+Triggered when you push to the repository, except when pushing tags.
+It generates one event per modified branch.
 
 **Request header**:
 
@@ -332,6 +333,7 @@ X-Gitlab-Event: System Hook
 ## Tag events
 
 Triggered when you create (or delete) tags to the repository.
+It generates one event per modified tag.
 
 **Request header**:
 
@@ -381,3 +383,49 @@ X-Gitlab-Event: System Hook
   "total_commits_count": 0
 }
 ```
+## Repository Update events
+
+Triggered only once when you push to the repository (including tags).
+
+**Request header**:
+
+```
+X-Gitlab-Event: System Hook
+```
+
+**Request body:**
+
+```json
+{
+  "event_name": "repository_update",
+  "user_id": 1,
+  "user_name": "John Smith",
+  "user_email": "admin@example.com",
+  "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
+  "project_id": 1,
+  "project": {
+    "name":"Example",
+    "description":"",
+    "web_url":"http://example.com/jsmith/example",
+    "avatar_url":null,
+    "git_ssh_url":"git@example.com:jsmith/example.git",
+    "git_http_url":"http://example.com/jsmith/example.git",
+    "namespace":"Jsmith",
+    "visibility_level":0,
+    "path_with_namespace":"jsmith/example",
+    "default_branch":"master",
+    "homepage":"http://example.com/jsmith/example",
+    "url":"git@example.com:jsmith/example.git",
+    "ssh_url":"git@example.com:jsmith/example.git",
+    "http_url":"http://example.com/jsmith/example.git",
+  },
+  "changes": [
+    {
+      "before":"8205ea8d81ce0c6b90fbe8280d118cc9fdad6130",
+      "after":"4045ea7a3df38697b3730a20fb73c8bed8a3e69e",
+      "ref":"refs/heads/master"
+    }
+  ],
+  "refs":["refs/heads/master"]
+}
+```
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 00d494f02f56dbcb79fff8c43d1877860ec73cad..3fc2b453eb61608adb673f815ddca28f911e206f 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -53,7 +53,7 @@ module API
     end
 
     class Hook < Grape::Entity
-      expose :id, :url, :created_at, :push_events, :tag_push_events
+      expose :id, :url, :created_at, :push_events, :tag_push_events, :repository_update_events
       expose :enable_ssl_verification
     end
 
diff --git a/lib/gitlab/data_builder/repository.rb b/lib/gitlab/data_builder/repository.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b42dc0529494be932dbb22918063bd5208f0f94c
--- /dev/null
+++ b/lib/gitlab/data_builder/repository.rb
@@ -0,0 +1,35 @@
+module Gitlab
+  module DataBuilder
+    module Repository
+      extend self
+
+      # Produce a hash of post-receive data
+      def update(project, user, changes, refs)
+        {
+          event_name: 'repository_update',
+
+          user_id: user.id,
+          user_name: user.name,
+          user_email: user.email,
+          user_avatar: user.avatar_url,
+
+          project_id: project.id,
+          project: project.hook_attrs,
+
+          changes: changes,
+
+          refs: refs
+        }
+      end
+
+      # Produce a hash of partial data for a single change
+      def single_change(oldrev, newrev, ref)
+        {
+          before: oldrev,
+          after: newrev,
+          ref: ref
+        }
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/git_post_receive.rb b/lib/gitlab/git_post_receive.rb
index 0e14253ab4e87e665e3ac669cb554d78868ddbae..742118b76a802aa810d98d9e93a233d6cbf51ba0 100644
--- a/lib/gitlab/git_post_receive.rb
+++ b/lib/gitlab/git_post_receive.rb
@@ -13,6 +13,16 @@ module Gitlab
       super(identifier, project, revision)
     end
 
+    def changes_refs
+      return enum_for(:changes_refs) unless block_given?
+
+      changes.each do |change|
+        oldrev, newrev, ref = change.strip.split(' ')
+
+        yield oldrev, newrev, ref
+      end
+    end
+
     private
 
     def deserialize_changes(changes)
diff --git a/spec/controllers/admin/hooks_controller_spec.rb b/spec/controllers/admin/hooks_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1d1070e90f41aac6bd3b23359539621c474fb86d
--- /dev/null
+++ b/spec/controllers/admin/hooks_controller_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+describe Admin::HooksController do
+  let(:admin) { create(:admin) }
+
+  before do
+    sign_in(admin)
+  end
+
+  describe 'POST #create' do
+    it 'sets all parameters' do
+      hook_params = {
+        enable_ssl_verification: true,
+        push_events: true,
+        tag_push_events: true,
+        repository_update_events: true,
+        token: "TEST TOKEN",
+        url: "http://example.com"
+      }
+
+      post :create, hook: hook_params
+
+      expect(response).to have_http_status(302)
+      expect(SystemHook.all.size).to eq(1)
+      expect(SystemHook.first).to have_attributes(hook_params)
+    end
+  end
+end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index f63fb7aeec6fc6449ff4c10ed32af51af1d33a4b..2b95f76e0453788c797a41851feb647d7d7a0803 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -317,6 +317,7 @@ ProjectHook:
 - token
 - group_id
 - confidential_issues_events
+- repository_update_events
 ProtectedBranch:
 - id
 - project_id
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index 8acec80558402593756db6c66cc12e33ac949f2a..4340170888dd5d0cdda6315b15f3808059d2f434 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -1,6 +1,19 @@
 require "spec_helper"
 
 describe SystemHook, models: true do
+  context 'default attributes' do
+    let(:system_hook) { build(:system_hook) }
+
+    it 'sets defined default parameters' do
+      attrs = {
+        push_events: false,
+        repository_update_events: true,
+        enable_ssl_verification: true
+      }
+      expect(system_hook).to have_attributes(attrs)
+    end
+  end
+
   describe "execute" do
     let(:system_hook) { create(:system_hook) }
     let(:user)        { create(:user) }
@@ -105,4 +118,12 @@ describe SystemHook, models: true do
       ).once
     end
   end
+
+  describe '.repository_update_hooks' do
+    it 'returns hooks for repository update events only' do
+      hook = create(:system_hook, repository_update_events: true)
+      create(:system_hook, repository_update_events: false)
+      expect(SystemHook.repository_update_hooks).to eq([hook])
+    end
+  end
 end
diff --git a/spec/requests/api/system_hooks_spec.rb b/spec/requests/api/system_hooks_spec.rb
index c7b8417357029657b9a5f58ce634b568bde79967..2eb191d60496803290c6f33a9d5fe94d00d91b70 100644
--- a/spec/requests/api/system_hooks_spec.rb
+++ b/spec/requests/api/system_hooks_spec.rb
@@ -32,8 +32,9 @@ describe API::SystemHooks do
         expect(response).to include_pagination_headers
         expect(json_response).to be_an Array
         expect(json_response.first['url']).to eq(hook.url)
-        expect(json_response.first['push_events']).to be true
+        expect(json_response.first['push_events']).to be false
         expect(json_response.first['tag_push_events']).to be false
+        expect(json_response.first['repository_update_events']).to be true
       end
     end
   end
diff --git a/spec/requests/api/v3/system_hooks_spec.rb b/spec/requests/api/v3/system_hooks_spec.rb
index 72c7d14b8ba8cf8ac626ed87ab0c0a566a7a23c5..ae427541abb264cdd55f66114ecad8774a23407b 100644
--- a/spec/requests/api/v3/system_hooks_spec.rb
+++ b/spec/requests/api/v3/system_hooks_spec.rb
@@ -31,8 +31,9 @@ describe API::V3::SystemHooks do
         expect(response).to have_http_status(200)
         expect(json_response).to be_an Array
         expect(json_response.first['url']).to eq(hook.url)
-        expect(json_response.first['push_events']).to be true
+        expect(json_response.first['push_events']).to be false
         expect(json_response.first['tag_push_events']).to be false
+        expect(json_response.first['repository_update_events']).to be true
       end
     end
   end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 0260416dbe2e590a2d395bb424eda71b2244c865..3289c2df1fbf6f72706f22d88eda9b85aa15753c 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -9,7 +9,7 @@ describe PostReceive do
   let(:key) { create(:key, user: project.owner) }
   let(:key_id) { key.shell_id }
 
-  context "as a resque worker" do
+  context "as a sidekiq worker" do
     it "reponds to #perform" do
       expect(described_class.new).to respond_to(:perform)
     end
@@ -93,6 +93,27 @@ describe PostReceive do
     end
   end
 
+  describe '#process_repository_update' do
+    let(:changes) {'123456 789012 refs/heads/tést'}
+    let(:fake_hook_data) do
+      { event_name: 'repository_update' }
+    end
+
+    before do
+      allow_any_instance_of(Gitlab::GitPostReceive).to receive(:identify).and_return(project.owner)
+      allow_any_instance_of(Gitlab::DataBuilder::Repository).to receive(:update).and_return(fake_hook_data)
+      # silence hooks so we can isolate
+      allow_any_instance_of(Key).to receive(:post_create_hook).and_return(true)
+      allow(subject).to receive(:process_project_changes).and_return(true)
+    end
+
+    it 'calls SystemHooksService' do
+      expect_any_instance_of(SystemHooksService).to receive(:execute_hooks).with(fake_hook_data, :repository_update_hooks).and_return(true)
+
+      subject.perform(pwd(project), key_id, base64_changes)
+    end
+  end
+
   context "webhook" do
     it "fetches the correct project" do
       expect(Project).to receive(:find_by).with(id: project.id.to_s)