diff --git a/docs/configuration.md b/docs/configuration.md
index 49e73039d498f8b54ddf8e463c54f009ed4c34b9..889e7282317b28c37ca48b2c4e96795b7937c8aa 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -85,6 +85,7 @@ $ node renovate --help
     --recreate-closed [boolean]          Recreate PRs even if same ones were closed previously
     --rebase-stale-prs [boolean]         Rebase stale PRs (GitHub only)
     --pr-creation <string>               When to create the PR for a branch. Values: immediate, not-pending, status-success.
+    --automerge <string>                 What types of upgrades to merge to base branch automatically. Values: none, minor or any
     --maintain-yarn-lock [boolean]       Keep yarn.lock files updated in base branch
     --group-name <string>                Human understandable name for the dependency group
     --group-slug <string>                Slug to use for group (e.g. in branch name). Will be calculated from groupName if null
@@ -140,6 +141,7 @@ Obviously, you can't set repository or package file location with this method.
 | `recreateClosed` | Recreate PRs even if same ones were closed previously | boolean | `false` | `RENOVATE_RECREATE_CLOSED` | `--recreate-closed` |
 | `rebaseStalePrs` | Rebase stale PRs (GitHub only) | boolean | `false` | `RENOVATE_REBASE_STALE_PRS` | `--rebase-stale-prs` |
 | `prCreation` | When to create the PR for a branch. Values: immediate, not-pending, status-success. | string | `"immediate"` | `RENOVATE_PR_CREATION` | `--pr-creation` |
+| `automerge` | What types of upgrades to merge to base branch automatically. Values: none, minor or any | string | `"none"` | `RENOVATE_AUTOMERGE` | `--automerge` |
 | `branchName` | Branch name template | string | `"renovate/{{depName}}-{{newVersionMajor}}.x"` |  |  |
 | `commitMessage` | Commit message template | string | `"Update dependency {{depName}} to version {{newVersion}}"` |  |  |
 | `prTitle` | Pull Request title template | string | `"{{#if isPin}}Pin{{else}}Update{{/if}} dependency {{depName}} to version {{#if isRange}}{{newVersion}}{{else}}{{#if isMajor}}{{newVersionMajor}}.x{{else}}{{newVersion}}{{/if}}{{/if}}"` |  |  |
diff --git a/lib/api/github.js b/lib/api/github.js
index e90992511af2442befffc267c950b2c7e5e61aa4..c33c3fd7d19e2706755c67b2ffcdefb2b0fa3199 100644
--- a/lib/api/github.js
+++ b/lib/api/github.js
@@ -21,6 +21,7 @@ module.exports = {
   createPr,
   getPr,
   updatePr,
+  mergePr,
   // file
   commitFilesToBranch,
   getFile,
@@ -45,10 +46,17 @@ async function initRepo(repoName, token, endpoint) {
     config.owner = res.body.owner.login;
     logger.debug(`${repoName} owner = ${config.owner}`);
     config.defaultBranch = res.body.default_branch;
+    if (res.body.allow_rebase_merge) {
+      config.mergeMethod = 'rebase';
+    } else if (res.body.allow_squash_merge) {
+      config.mergeMethod = 'squash';
+    } else {
+      config.mergeMethod = 'merge';
+    }
     logger.debug(`${repoName} default branch = ${config.defaultBranch}`);
     config.baseCommitSHA = await getBranchCommit(config.defaultBranch);
     config.baseTreeSHA = await getCommitTree(config.baseCommitSHA);
-  } catch (err) {
+  } catch (err) /* istanbul ignore next */ {
     logger.error(`GitHub init error: ${JSON.stringify(err)}`);
     throw err;
   }
@@ -241,6 +249,16 @@ async function updatePr(prNo, title, body) {
   });
 }
 
+async function mergePr(pr) {
+  await ghGot.put(`repos/${config.repoName}/pulls/${pr.number}/merge`, {
+    body: {
+      merge_method: config.mergeMethod,
+    },
+  });
+  // Delete branch
+  await ghGot.delete(`repos/${config.repoName}/git/refs/heads/${pr.head.ref}`);
+}
+
 // Generic File operations
 
 async function getFile(filePath, branchName = config.defaultBranch) {
diff --git a/lib/api/gitlab.js b/lib/api/gitlab.js
index 24022584a833886e82c4f9fa1575510ac36914e8..64889312b35cb0b1103fcf46cb26631944d060f5 100644
--- a/lib/api/gitlab.js
+++ b/lib/api/gitlab.js
@@ -21,6 +21,7 @@ module.exports = {
   createPr,
   getPr,
   updatePr,
+  mergePr,
   // file
   commitFilesToBranch,
   getFile,
@@ -236,6 +237,14 @@ async function updatePr(prNo, title, body) {
   });
 }
 
+async function mergePr(pr) {
+  await glGot.put(`projects/${config.repoName}/merge_requests/${pr.number}/merge`, {
+    body: {
+      should_remove_source_branch: true,
+    },
+  });
+}
+
 // Generic File operations
 
 async function getFile(filePath, branchName = config.defaultBranch) {
diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index 43f4ef74b4291e055ffcefcc3cf1d46a6dc81594..700a37585981bfa9937f589e9e89e8004854cabc 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -93,6 +93,13 @@ const options = [
     type: 'string',
     default: 'immediate',
   },
+  // Automatic merging
+  {
+    name: 'automerge',
+    description: 'What types of upgrades to merge to base branch automatically. Values: none, minor or any',
+    type: 'string',
+    default: 'none',
+  },
   // String templates
   {
     name: 'branchName',
diff --git a/lib/helpers/versions.js b/lib/helpers/versions.js
index 0fa20a57f0892d753e09b01da3e95d1ec333f03e..9c4f418b5103282c9874edb8bb463774c5b19307 100644
--- a/lib/helpers/versions.js
+++ b/lib/helpers/versions.js
@@ -56,7 +56,8 @@ function determineUpgrades(dep, currentVersion, config) {
     .forEach((newVersion) => {
       // Group by major versions
       const newVersionMajor = semver.major(newVersion);
-      const separateMajors = config.separateMajorReleases && !config.groupName;
+      // Only split majors if configured to do so, and no group or 'any' automerge
+      const separateMajors = config.separateMajorReleases && !config.groupName && config.automerge !== 'any';
       const upgradeKey = separateMajors ? newVersionMajor : 'latest';
       // Save this, if it's a new major version or greater than the previous greatest
       if (!allUpgrades[upgradeKey] ||
diff --git a/lib/worker.js b/lib/worker.js
index bfeeb3969ab5bd59dfa9adfbe0e0a63b537af70e..818d48748ba12fea0661162bce617d59c385da72 100644
--- a/lib/worker.js
+++ b/lib/worker.js
@@ -208,7 +208,10 @@ async function updateBranch(upgrades) {
     }
     const branchCreated = await branchWorker.ensureBranch(upgrades);
     if (branchCreated) {
-      await prWorker.ensurePr(upgrade0);
+      const pr = await prWorker.ensurePr(upgrade0);
+      if (pr) {
+        await prWorker.checkAutoMerge(pr, upgrade0);
+      }
     }
   } catch (error) {
     logger.error(`Error updating branch ${branchName}: ${error}`);
diff --git a/lib/workers/pr.js b/lib/workers/pr.js
index a019e9bfd77cfa74a6c30876200d6c7076d3f0bb..c99c1ea3d96b4ff4a2badb0dd983c7ef5d3df4e6 100644
--- a/lib/workers/pr.js
+++ b/lib/workers/pr.js
@@ -4,6 +4,7 @@ const getChangeLog = require('../helpers/changelog');
 
 module.exports = {
   ensurePr,
+  checkAutoMerge,
 };
 
 // Ensures that PR exists with matching title/body
@@ -69,3 +70,29 @@ async function ensurePr(upgradeConfig) {
   }
   return null;
 }
+
+async function checkAutoMerge(pr, config) {
+  logger.debug(`Checking #${pr.number} for automerge`);
+  if (config.automerge === 'any' ||
+    (config.automerge === 'minor' && config.upgradeType === 'minor')) {
+    logger.verbose('PR is configured for automerge');
+    logger.debug(JSON.stringify(pr));
+    // Return if PR not ready for automerge
+    if (pr.mergeable !== true || pr.mergeable_state === 'unstable') {
+      logger.verbose('PR is not ready for merge');
+      return;
+    }
+    // Check branch status
+    const branchStatus = await config.api.getBranchStatus(pr.head.ref);
+    logger.debug(`branchStatus=${branchStatus}`);
+    if (branchStatus !== 'success') {
+      logger.verbose('Branch status is not "success"');
+      return;
+    }
+    // Let's merge this
+    logger.info(`Automerging #${pr.number}`);
+    await config.api.mergePr(pr);
+  } else {
+    logger.verbose('No automerge');
+  }
+}
diff --git a/readme.md b/readme.md
index ea348ed0f9348c6d082facf711c5e3cf1f09b55a..f50a48db38f4c988ffe4a44bd870e97a81e7eb01 100644
--- a/readme.md
+++ b/readme.md
@@ -54,6 +54,7 @@ $ node renovate --help
     --recreate-closed [boolean]          Recreate PRs even if same ones were closed previously
     --rebase-stale-prs [boolean]         Rebase stale PRs (GitHub only)
     --pr-creation <string>               When to create the PR for a branch. Values: immediate, not-pending, status-success.
+    --automerge <string>                 What types of upgrades to merge to base branch automatically. Values: none, minor or any
     --maintain-yarn-lock [boolean]       Keep yarn.lock files updated in base branch
     --group-name <string>                Human understandable name for the dependency group
     --group-slug <string>                Slug to use for group (e.g. in branch name). Will be calculated from groupName if null
diff --git a/test/api/__snapshots__/github.spec.js.snap b/test/api/__snapshots__/github.spec.js.snap
index 62d554f0b96ae474dd848c62b1c10619b7c74642..f3308236b93373f26aede528952d25656739ed77 100644
--- a/test/api/__snapshots__/github.spec.js.snap
+++ b/test/api/__snapshots__/github.spec.js.snap
@@ -652,6 +652,7 @@ Object {
   "baseCommitSHA": "1234",
   "baseTreeSHA": "5678",
   "defaultBranch": "master",
+  "mergeMethod": "rebase",
   "owner": "theowner",
   "repoName": "some/repo",
 }
@@ -676,6 +677,7 @@ Object {
   "baseCommitSHA": "1234",
   "baseTreeSHA": "5678",
   "defaultBranch": "master",
+  "mergeMethod": "rebase",
   "owner": "theowner",
   "repoName": "some/repo",
 }
@@ -700,11 +702,55 @@ Object {
   "baseCommitSHA": "1234",
   "baseTreeSHA": "5678",
   "defaultBranch": "master",
+  "mergeMethod": "rebase",
   "owner": "theowner",
   "repoName": "some/repo",
 }
 `;
 
+exports[`api/github initRepo should merge 1`] = `
+Object {
+  "baseCommitSHA": "1234",
+  "baseTreeSHA": "5678",
+  "defaultBranch": "master",
+  "mergeMethod": "merge",
+  "owner": "theowner",
+  "repoName": "some/repo",
+}
+`;
+
+exports[`api/github initRepo should squash 1`] = `
+Object {
+  "baseCommitSHA": "1234",
+  "baseTreeSHA": "5678",
+  "defaultBranch": "master",
+  "mergeMethod": "squash",
+  "owner": "theowner",
+  "repoName": "some/repo",
+}
+`;
+
+exports[`api/github mergePr(prNo) should merge the PR 1`] = `
+Array [
+  Array [
+    "repos/some/repo/pulls/1234/merge",
+    Object {
+      "body": Object {
+        "merge_method": "rebase",
+      },
+    },
+  ],
+]
+`;
+
+exports[`api/github mergePr(prNo) should merge the PR 2`] = `
+Array [
+  Array [
+    "repos/some/repo/git/refs/heads/someref",
+  ],
+]
+`;
+
 exports[`api/github updatePr(prNo, title, body) should update the PR 1`] = `
 Array [
   Array [
diff --git a/test/api/github.spec.js b/test/api/github.spec.js
index de08142728cea576378d7a9ec3598b6714d66f6e..0cbae5e55d97788d9227557f69aabdcb6dc01c1a 100644
--- a/test/api/github.spec.js
+++ b/test/api/github.spec.js
@@ -21,6 +21,8 @@ describe('api/github', () => {
           login: 'theowner',
         },
         default_branch: 'master',
+        allow_rebase_merge: true,
+        allow_squash_merge: true,
       },
     }));
     // getBranchCommit
@@ -68,6 +70,74 @@ describe('api/github', () => {
       }
       expect(err.message).toBe('No token found for GitHub repository some/repo');
     });
+    it('should squash', async () => {
+      async function squashInitRepo(...args) {
+        // repo info
+        ghGot.mockImplementationOnce(() => ({
+          body: {
+            owner: {
+              login: 'theowner',
+            },
+            default_branch: 'master',
+            allow_rebase_merge: false,
+            allow_squash_merge: true,
+          },
+        }));
+        // getBranchCommit
+        ghGot.mockImplementationOnce(() => ({
+          body: {
+            object: {
+              sha: '1234',
+            },
+          },
+        }));
+        // getCommitTree
+        ghGot.mockImplementationOnce(() => ({
+          body: {
+            tree: {
+              sha: '5678',
+            },
+          },
+        }));
+        return github.initRepo(...args);
+      }
+      const config = await squashInitRepo('some/repo', 'token');
+      expect(config).toMatchSnapshot();
+    });
+    it('should merge', async () => {
+      async function mergeInitRepo(...args) {
+        // repo info
+        ghGot.mockImplementationOnce(() => ({
+          body: {
+            owner: {
+              login: 'theowner',
+            },
+            default_branch: 'master',
+            allow_rebase_merge: false,
+            allow_squash_merge: false,
+          },
+        }));
+        // getBranchCommit
+        ghGot.mockImplementationOnce(() => ({
+          body: {
+            object: {
+              sha: '1234',
+            },
+          },
+        }));
+        // getCommitTree
+        ghGot.mockImplementationOnce(() => ({
+          body: {
+            tree: {
+              sha: '5678',
+            },
+          },
+        }));
+        return github.initRepo(...args);
+      }
+      const config = await mergeInitRepo('some/repo', 'token');
+      expect(config).toMatchSnapshot();
+    });
   });
   describe('findFilePaths(fileName)', () => {
     it('should return the files matching the fileName', async () => {
@@ -394,6 +464,20 @@ describe('api/github', () => {
       expect(ghGot.patch.mock.calls).toMatchSnapshot();
     });
   });
+  describe('mergePr(prNo)', () => {
+    it('should merge the PR', async () => {
+      await initRepo('some/repo', 'token');
+      const pr = {
+        number: 1234,
+        head: {
+          ref: 'someref',
+        },
+      };
+      await github.mergePr(pr);
+      expect(ghGot.put.mock.calls).toMatchSnapshot();
+      expect(ghGot.delete.mock.calls).toMatchSnapshot();
+    });
+  });
   describe('getFile(filePatch, branchName)', () => {
     it('should return the encoded file content', async () => {
       await initRepo('some/repo', 'token');
diff --git a/test/helpers/__snapshots__/versions.spec.js.snap b/test/helpers/__snapshots__/versions.spec.js.snap
index 21b5eb1adc48bdf09cbe02696b44d70e97229cc4..b06d296211433024807eff9dfc6b4e25b72335f0 100644
--- a/test/helpers/__snapshots__/versions.spec.js.snap
+++ b/test/helpers/__snapshots__/versions.spec.js.snap
@@ -1,5 +1,36 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`helpers/versions .determineUpgrades(dep, currentVersion, defaultConfig) returns both updates if automerging minor 1`] = `
+Array [
+  Object {
+    "changeLogFromVersion": "0.4.4",
+    "changeLogToVersion": "0.9.7",
+    "newVersion": "0.9.7",
+    "newVersionMajor": 0,
+    "upgradeType": "minor",
+  },
+  Object {
+    "changeLogFromVersion": "0.4.4",
+    "changeLogToVersion": "1.4.1",
+    "newVersion": "1.4.1",
+    "newVersionMajor": 1,
+    "upgradeType": "major",
+  },
+]
+`;
+
+exports[`helpers/versions .determineUpgrades(dep, currentVersion, defaultConfig) returns only one update if automerging any 1`] = `
+Array [
+  Object {
+    "changeLogFromVersion": "0.4.4",
+    "changeLogToVersion": "1.4.1",
+    "newVersion": "1.4.1",
+    "newVersionMajor": 1,
+    "upgradeType": "major",
+  },
+]
+`;
+
 exports[`helpers/versions .determineUpgrades(dep, currentVersion, defaultConfig) returns only one update if grouping 1`] = `
 Array [
   Object {
diff --git a/test/helpers/versions.spec.js b/test/helpers/versions.spec.js
index 17bee80d39de20ef23fb0665739a3cb8923d6ba8..c5f23210bfd91db080622af6fb864290096cae3a 100644
--- a/test/helpers/versions.spec.js
+++ b/test/helpers/versions.spec.js
@@ -48,6 +48,14 @@ describe('helpers/versions', () => {
       defaultConfig.groupName = 'somegroup';
       expect(versionsHelper.determineUpgrades(qJson, '^0.4.0', defaultConfig)).toMatchSnapshot();
     });
+    it('returns only one update if automerging any', () => {
+      defaultConfig.automerge = 'any';
+      expect(versionsHelper.determineUpgrades(qJson, '^0.4.0', defaultConfig)).toMatchSnapshot();
+    });
+    it('returns both updates if automerging minor', () => {
+      defaultConfig.automerge = 'minor';
+      expect(versionsHelper.determineUpgrades(qJson, '^0.4.0', defaultConfig)).toMatchSnapshot();
+    });
     it('disables major release separation (major)', () => {
       const config = Object.assign({}, defaultConfig, { separateMajorReleases: false });
       const upgradeVersions = [
diff --git a/test/workers/pr.spec.js b/test/workers/pr.spec.js
index 2ec90424d56c1eee3ca023559b73173bcdb4ce3d..3411fa864d8cc22b91165c5f11e0a885142cc1ce 100644
--- a/test/workers/pr.spec.js
+++ b/test/workers/pr.spec.js
@@ -8,6 +8,68 @@ const getChangeLog = jest.fn();
 getChangeLog.mockReturnValue('Mocked changelog');
 
 describe('workers/pr', () => {
+  describe('checkAutoMerge(pr, config)', () => {
+    let config;
+    let pr;
+    beforeEach(() => {
+      config = Object.assign({}, defaultConfig);
+      pr = {
+        head: {
+          ref: 'somebranch',
+        },
+      };
+      config.api = {
+        mergePr: jest.fn(),
+        getBranchStatus: jest.fn(),
+      };
+    });
+    it('should not automerge if not configured', async () => {
+      await prWorker.checkAutoMerge(pr, config);
+      expect(config.api.mergePr.mock.calls.length).toBe(0);
+    });
+    it('should automerge if any and pr is mergeable', async () => {
+      config.automerge = 'any';
+      pr.mergeable = true;
+      config.api.getBranchStatus.mockReturnValueOnce('success');
+      await prWorker.checkAutoMerge(pr, config);
+      expect(config.api.mergePr.mock.calls.length).toBe(1);
+    });
+    it('should not automerge if any and pr is mergeable but branch status is not success', async () => {
+      config.automerge = 'any';
+      pr.mergeable = true;
+      config.api.getBranchStatus.mockReturnValueOnce('pending');
+      await prWorker.checkAutoMerge(pr, config);
+      expect(config.api.mergePr.mock.calls.length).toBe(0);
+    });
+    it('should not automerge if any and pr is mergeable but unstable', async () => {
+      config.automerge = 'any';
+      pr.mergeable = true;
+      pr.mergeable_state = 'unstable';
+      await prWorker.checkAutoMerge(pr, config);
+      expect(config.api.mergePr.mock.calls.length).toBe(0);
+    });
+    it('should not automerge if any and pr is unmergeable', async () => {
+      config.automerge = 'any';
+      pr.mergeable = false;
+      await prWorker.checkAutoMerge(pr, config);
+      expect(config.api.mergePr.mock.calls.length).toBe(0);
+    });
+    it('should automerge if minor and upgradeType is minor', async () => {
+      config.automerge = 'minor';
+      config.upgradeType = 'minor';
+      pr.mergeable = true;
+      config.api.getBranchStatus.mockReturnValueOnce('success');
+      await prWorker.checkAutoMerge(pr, config);
+      expect(config.api.mergePr.mock.calls.length).toBe(1);
+    });
+    it('should not automerge if minor and upgradeType is major', async () => {
+      config.automerge = 'minor';
+      config.upgradeType = 'major';
+      pr.mergeable = true;
+      await prWorker.checkAutoMerge(pr, config);
+      expect(config.api.mergePr.mock.calls.length).toBe(0);
+    });
+  });
   describe('ensurePr(config)', () => {
     let config;
     let existingPr;