diff --git a/docs/configuration.md b/docs/configuration.md
index 25a10f35e35dda783fe079fe5814c4a05b9bd6ce..0b28c3763f70a098db3836fb716a441b82cdfff8 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -88,6 +88,7 @@ $ node renovate --help
     --ignore-deps <list>                 Dependencies to ignore
     --pin-versions [boolean]             Convert ranged versions in package.json to pinned versions
     --separate-major-releases [boolean]  If set to false, it will upgrade dependencies to latest release only, and not separate major/minor branches
+    --separate-patch-releases [boolean]  If set to true, it will separate minor and patch updates into separate branches
     --ignore-future [boolean]            Ignore versions tagged as "future"
     --ignore-unstable [boolean]          Ignore versions with unstable semver
     --respect-latest [boolean]           Ignore versions newer than npm "latest" version
@@ -332,6 +333,14 @@ Obviously, you can't set repository or package file location with this method.
   <td>`RENOVATE_SEPARATE_MAJOR_RELEASES`</td>
   <td>`--separate-major-releases`<td>
 </tr>
+<tr>
+  <td>`separatePatchReleases`</td>
+  <td>If set to true, it will separate minor and patch updates into separate branches</td>
+  <td>boolean</td>
+  <td><pre>false</pre></td>
+  <td>`RENOVATE_SEPARATE_PATCH_RELEASES`</td>
+  <td>`--separate-patch-releases`<td>
+</tr>
 <tr>
   <td>`ignoreFuture`</td>
   <td>Ignore versions tagged as "future"</td>
@@ -356,6 +365,30 @@ Obviously, you can't set repository or package file location with this method.
   <td>`RENOVATE_RESPECT_LATEST`</td>
   <td>`--respect-latest`<td>
 </tr>
+<tr>
+  <td>`major`</td>
+  <td>Configuration to apply when an update type is major</td>
+  <td>json</td>
+  <td><pre>{}</pre></td>
+  <td>`RENOVATE_MAJOR`</td>
+  <td><td>
+</tr>
+<tr>
+  <td>`minor`</td>
+  <td>Configuration to apply when an update type is minor</td>
+  <td>json</td>
+  <td><pre>{}</pre></td>
+  <td>`RENOVATE_MINOR`</td>
+  <td><td>
+</tr>
+<tr>
+  <td>`patch`</td>
+  <td>Configuration to apply when an update type is patch. Only applies if `separatePatchReleases` is set to true</td>
+  <td>json</td>
+  <td><pre>{"branchName": "renovate/{{depName}}-{{newVersionMajor}}.{newVersionMinor}}.x"}</pre></td>
+  <td>`RENOVATE_PATCH`</td>
+  <td><td>
+</tr>
 <tr>
   <td>`semanticCommits`</td>
   <td>Enable semantic commit prefixes for commits and PR titles</td>
@@ -448,7 +481,7 @@ Obviously, you can't set repository or package file location with this method.
   <td>`prBody`</td>
   <td>Pull Request body template</td>
   <td>string</td>
-  <td><pre>"This {{#if isGitHub}}Pull{{else}}Merge{{/if}} Request {{#if isRollback}}rolls back{{else}}updates{{/if}} dependency [{{depName}}]({{repositoryUrl}}) from version `{{currentVersion}}` to `{{newVersion}}`{{#if isRollback}}. This is necessary and important because version `{{currentVersion}}` cannot be found in the npm registry - probably because of it being unpublished.{{/if}}\n{{#if releases.length}}\n\n{{#if schedule}}\n**Note**: This PR was created on a configured schedule (\"{{schedule}}\"{{#if timezone}} in timezone `{{timezone}}`{{/if}}) and will not receive updates outside those times.\n{{/if}}\n\n### Commits\n\n<details>\n<summary>{{githubName}}</summary>\n\n{{#each releases as |release|}}\n#### {{release.version}}\n{{#each release.commits as |commit|}}\n-   [`{{commit.shortSha}}`]({{commit.url}}) {{commit.message}}\n{{/each}}\n{{/each}}\n\n</details>\n{{/if}}\n\n{{#if hasErrors}}\n\n---\n\n### Errors\n\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\n\n{{#each errors as |error|}}\n-   `{{error.depName}}`: {{error.message}}\n{{/each}}\n{{/if}}\n\n{{#if hasWarnings}}\n\n---\n\n### Warnings\n\nPlease make sure the following warnings are safe to ignore:\n\n{{#each warnings as |warning|}}\n-   `{{warning.depName}}`: {{warning.message}}\n{{/each}}\n{{/if}}\n\n---\n\nThis {{#if isGitHub}}PR{{else}}MR{{/if}} has been generated by [Renovate Bot](https://renovateapp.com)."</pre></td>
+  <td><pre>"This {{#if isGitHub}}Pull{{else}}Merge{{/if}} Request {{#if isRollback}}rolls back{{else}}updates{{/if}} dependency {{#if repositoryUrl}}[{{depName}}]({{repositoryUrl}}){{else}}`{{depName}}`{{/if}} from version `{{currentVersion}}` to `{{newVersion}}`{{#if isRollback}}. This is necessary and important because version `{{currentVersion}}` cannot be found in the npm registry - probably because of it being unpublished.{{/if}}\n{{#if releases.length}}\n\n{{#if schedule}}\n**Note**: This PR was created on a configured schedule (\"{{schedule}}\"{{#if timezone}} in timezone `{{timezone}}`{{/if}}) and will not receive updates outside those times.\n{{/if}}\n\n### Commits\n\n<details>\n<summary>{{githubName}}</summary>\n\n{{#each releases as |release|}}\n#### {{release.version}}\n{{#each release.commits as |commit|}}\n-   [`{{commit.shortSha}}`]({{commit.url}}) {{commit.message}}\n{{/each}}\n{{/each}}\n\n</details>\n{{/if}}\n\n{{#if hasErrors}}\n\n---\n\n### Errors\n\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\n\n{{#each errors as |error|}}\n-   `{{error.depName}}`: {{error.message}}\n{{/each}}\n{{/if}}\n\n{{#if hasWarnings}}\n\n---\n\n### Warnings\n\nPlease make sure the following warnings are safe to ignore:\n\n{{#each warnings as |warning|}}\n-   `{{warning.depName}}`: {{warning.message}}\n{{/each}}\n{{/if}}\n\n---\n\nThis {{#if isGitHub}}PR{{else}}MR{{/if}} has been generated by [Renovate Bot](https://renovateapp.com)."</pre></td>
   <td>`RENOVATE_PR_BODY`</td>
   <td><td>
 </tr>
@@ -510,7 +543,7 @@ Obviously, you can't set repository or package file location with this method.
   "branchName": "renovate/{{groupSlug}}",
   "commitMessage": "{{semanticPrefix}}Renovate {{groupName}} packages",
   "prTitle": "{{semanticPrefix}}Renovate {{groupName}} packages",
-  "prBody": "This {{#if isGitHub}}Pull{{else}}Merge{{/if}} Request renovates the package group \"{{groupName}}\".\n\n{{#if schedule}}\n**Note**: This PR was created on a configured schedule (\"{{schedule}}\"{{#if timezone}} in timezone `{{timezone}}`{{/if}}) and will not receive updates outside those times.\n{{/if}}\n\n{{#each upgrades as |upgrade|}}\n-   [{{upgrade.depName}}]({{upgrade.repositoryUrl}}): from `{{upgrade.currentVersion}}` to `{{upgrade.newVersion}}`\n{{/each}}\n\n{{#unless isPin}}\n### Commits\n\n{{#each upgrades as |upgrade|}}\n{{#if upgrade.releases.length}}\n<details>\n<summary>{{upgrade.githubName}}</summary>\n{{#each upgrade.releases as |release|}}\n\n#### {{release.version}}\n{{#each release.commits as |commit|}}\n-   [`{{commit.shortSha}}`]({{commit.url}}){{commit.message}}\n{{/each}}\n{{/each}}\n\n</details>\n{{/if}}\n{{/each}}\n{{/unless}}\n<br />\n\n{{#if hasErrors}}\n\n---\n\n### Errors\n\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\n\n{{#each errors as |error|}}\n-   `{{error.depName}}`: {{error.message}}\n{{/each}}\n{{/if}}\n\n{{#if hasWarnings}}\n\n---\n\n### Warnings\n\nPlease make sure the following warnings are safe to ignore:\n\n{{#each warnings as |warning|}}\n-   `{{warning.depName}}`: {{warning.message}}\n{{/each}}\n{{/if}}\n\n---\n\nThis {{#if isGitHub}}PR{{else}}MR{{/if}} has been generated by [Renovate Bot](https://renovateapp.com)."
+  "prBody": "This {{#if isGitHub}}Pull{{else}}Merge{{/if}} Request renovates the package group \"{{groupName}}\".\n\n{{#if schedule}}\n**Note**: This PR was created on a configured schedule (\"{{schedule}}\"{{#if timezone}} in timezone `{{timezone}}`{{/if}}) and will not receive updates outside those times.\n{{/if}}\n\n{{#each upgrades as |upgrade|}}\n-   {{#if repositoryUrl}}[{{upgrade.depName}}]({{upgrade.repositoryUrl}}){{else}}`{{depName}}`{{/if}}: from `{{upgrade.currentVersion}}` to `{{upgrade.newVersion}}`\n{{/each}}\n\n{{#unless isPin}}\n### Commits\n\n{{#each upgrades as |upgrade|}}\n{{#if upgrade.releases.length}}\n<details>\n<summary>{{upgrade.githubName}}</summary>\n{{#each upgrade.releases as |release|}}\n\n#### {{release.version}}\n{{#each release.commits as |commit|}}\n-   [`{{commit.shortSha}}`]({{commit.url}}){{commit.message}}\n{{/each}}\n{{/each}}\n\n</details>\n{{/if}}\n{{/each}}\n{{/unless}}\n<br />\n\n{{#if hasErrors}}\n\n---\n\n### Errors\n\nRenovate encountered some errors when processing your repository, so you are being notified here even if they do not directly apply to this PR.\n\n{{#each errors as |error|}}\n-   `{{error.depName}}`: {{error.message}}\n{{/each}}\n{{/if}}\n\n{{#if hasWarnings}}\n\n---\n\n### Warnings\n\nPlease make sure the following warnings are safe to ignore:\n\n{{#each warnings as |warning|}}\n-   `{{warning.depName}}`: {{warning.message}}\n{{/each}}\n{{/if}}\n\n---\n\nThis {{#if isGitHub}}PR{{else}}MR{{/if}} has been generated by [Renovate Bot](https://renovateapp.com)."
 }</pre></td>
   <td></td>
   <td><td>
diff --git a/lib/config/definitions.js b/lib/config/definitions.js
index 4af6f08dbd4bda7713e2f12f3ab75f17b9312e24..554240c8be50946b7f2cd987f257400af8804a0a 100644
--- a/lib/config/definitions.js
+++ b/lib/config/definitions.js
@@ -185,6 +185,14 @@ const options = [
     stage: 'package',
     type: 'boolean',
   },
+  {
+    name: 'separatePatchReleases',
+    description:
+      'If set to true, it will separate minor and patch updates into separate branches',
+    stage: 'package',
+    type: 'boolean',
+    default: false,
+  },
   {
     name: 'ignoreFuture',
     description: 'Ignore versions tagged as "future"',
@@ -203,6 +211,38 @@ const options = [
     stage: 'package',
     type: 'boolean',
   },
+  // Major/Minor/Patch
+  {
+    name: 'major',
+    description: 'Configuration to apply when an update type is major',
+    stage: 'package',
+    type: 'json',
+    default: {},
+    cli: false,
+    mergeable: true,
+  },
+  {
+    name: 'minor',
+    description: 'Configuration to apply when an update type is minor',
+    stage: 'package',
+    type: 'json',
+    default: {},
+    cli: false,
+    mergeable: true,
+  },
+  {
+    name: 'patch',
+    description:
+      'Configuration to apply when an update type is patch. Only applies if `separatePatchReleases` is set to true',
+    stage: 'package',
+    type: 'json',
+    default: {
+      branchName:
+        'renovate/{{depName}}-{{newVersionMajor}}.{{newVersionMinor}}.x',
+    },
+    cli: false,
+    mergeable: true,
+  },
   // Semantic commit / Semantic release
   {
     name: 'semanticCommits',
diff --git a/lib/workers/package/index.js b/lib/workers/package/index.js
index 5494ba9500c3ca4f193af3269abd9bdd8253ed18..20b506433dfcb8cbd37188c3092440acda7cf7eb 100644
--- a/lib/workers/package/index.js
+++ b/lib/workers/package/index.js
@@ -49,7 +49,14 @@ async function renovatePackage(config) {
   logger.debug({ results }, `${config.depName} lookup results`);
   // Flatten the result on top of config, add repositoryUrl
   return results.map(result => {
-    const upg = configParser.mergeChildConfig(config, result);
+    let upg = configParser.mergeChildConfig(config, result);
+    if (upg.isMajor) {
+      upg = configParser.mergeChildConfig(upg, upg.major);
+    } else if (upg.isMinor) {
+      upg = configParser.mergeChildConfig(upg, upg.minor);
+    } else if (upg.isPatch) {
+      upg = configParser.mergeChildConfig(upg, upg.patch);
+    }
     upg.repositoryUrl =
       npmDep && npmDep.repositoryUrl && npmDep.repositoryUrl.length
         ? npmDep.repositoryUrl
diff --git a/lib/workers/package/versions.js b/lib/workers/package/versions.js
index 8a0b7ca023fd4f19afe494d98005c44302a85662..bd7dae0f44320f66909501ee5d83053b7bcefa2b 100644
--- a/lib/workers/package/versions.js
+++ b/lib/workers/package/versions.js
@@ -87,24 +87,38 @@ function determineUpgrades(npmDep, config) {
     .forEach(newVersion => {
       // Group by major versions
       const newVersionMajor = semver.major(newVersion);
-      // 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';
+      const newVersionMinor = semver.minor(newVersion);
+      let type;
+      if (newVersionMajor > semver.major(changeLogFromVersion)) {
+        type = 'major';
+      } else if (
+        newVersionMinor === semver.minor(changeLogFromVersion) &&
+        (config.separatePatchReleases || config.automerge === 'patch')
+      ) {
+        // Only use patch if configured to
+        type = 'patch';
+      } else {
+        type = 'minor';
+      }
+      let upgradeKey;
+      if (
+        !config.separateMajorReleases ||
+        config.groupName ||
+        config.automerge === 'any'
+      ) {
+        // If we're not separating releases then we use a common lookup key
+        upgradeKey = 'latest';
+      } else if (type === 'patch') {
+        upgradeKey = `{{newVersionMajor}}.{{newVersionMinor}}`;
+      } else {
+        // Use major version as lookup key
+        upgradeKey = newVersionMajor;
+      }
       // Save this, if it's a new major version or greater than the previous greatest
       if (
         !allUpgrades[upgradeKey] ||
         semver.gt(newVersion, allUpgrades[upgradeKey].newVersion)
       ) {
-        const newVersionMinor = semver.minor(newVersion);
-        const type =
-          newVersionMajor > semver.major(changeLogFromVersion) // eslint-disable-line no-nested-ternary
-            ? 'major'
-            : newVersionMinor > semver.minor(changeLogFromVersion)
-              ? 'minor'
-              : 'patch';
         const changeLogToVersion = newVersion;
         const automergeEnabled = isAutomergeEnabled(config.automerge, type);
         allUpgrades[upgradeKey] = {
diff --git a/test/workers/package/__snapshots__/index.spec.js.snap b/test/workers/package/__snapshots__/index.spec.js.snap
index 4160c5b53dec5990edc9b18eb1deb5faa0cb27d4..06814c44298c60ce1d653b7e9657b0b30dc99a1d 100644
--- a/test/workers/package/__snapshots__/index.spec.js.snap
+++ b/test/workers/package/__snapshots__/index.spec.js.snap
@@ -1,5 +1,35 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`lib/workers/package/index renovatePackage(config) merges type 1`] = `
+Array [
+  "timezone",
+  "schedule",
+  "semanticCommits",
+  "semanticPrefix",
+  "recreateClosed",
+  "rebaseStalePrs",
+  "prCreation",
+  "automerge",
+  "automergeType",
+  "requiredStatusChecks",
+  "branchName",
+  "commitMessage",
+  "prTitle",
+  "prBody",
+  "lazyGrouping",
+  "groupName",
+  "groupSlug",
+  "group",
+  "labels",
+  "assignees",
+  "reviewers",
+  "depName",
+  "currentVersion",
+  "isMajor",
+  "repositoryUrl",
+]
+`;
+
 exports[`lib/workers/package/index renovatePackage(config) returns array if upgrades found 1`] = `
 Array [
   "timezone",
diff --git a/test/workers/package/__snapshots__/versions.spec.js.snap b/test/workers/package/__snapshots__/versions.spec.js.snap
index d91ab568238a0a198a4a7ef1dd5b477ab58cde1c..a941f3bf26182994b8eb5acb616326c3f4be3899 100644
--- a/test/workers/package/__snapshots__/versions.spec.js.snap
+++ b/test/workers/package/__snapshots__/versions.spec.js.snap
@@ -153,17 +153,17 @@ Array [
 ]
 `;
 
-exports[`workers/package/versions .determineUpgrades(npmDep, config) returns both updates if automerging patch 1`] = `
+exports[`workers/package/versions .determineUpgrades(npmDep, config) returns minor update if separate patches not configured 1`] = `
 Array [
   Object {
-    "automergeEnabled": true,
+    "automergeEnabled": false,
     "changeLogFromVersion": "0.9.0",
     "changeLogToVersion": "0.9.7",
-    "isPatch": true,
+    "isMinor": true,
     "newVersion": "0.9.7",
     "newVersionMajor": 0,
     "newVersionMinor": 9,
-    "type": "patch",
+    "type": "minor",
   },
   Object {
     "automergeEnabled": false,
@@ -232,6 +232,91 @@ Array [
 ]
 `;
 
+exports[`workers/package/versions .determineUpgrades(npmDep, config) returns patch minor and major 1`] = `
+Array [
+  Object {
+    "automergeEnabled": false,
+    "changeLogFromVersion": "0.8.0",
+    "changeLogToVersion": "0.9.7",
+    "isMinor": true,
+    "newVersion": "0.9.7",
+    "newVersionMajor": 0,
+    "newVersionMinor": 9,
+    "type": "minor",
+  },
+  Object {
+    "automergeEnabled": false,
+    "changeLogFromVersion": "0.8.0",
+    "changeLogToVersion": "1.4.1",
+    "isMajor": true,
+    "newVersion": "1.4.1",
+    "newVersionMajor": 1,
+    "newVersionMinor": 4,
+    "type": "major",
+  },
+  Object {
+    "automergeEnabled": false,
+    "changeLogFromVersion": "0.8.0",
+    "changeLogToVersion": "0.8.12",
+    "isPatch": true,
+    "newVersion": "0.8.12",
+    "newVersionMajor": 0,
+    "newVersionMinor": 8,
+    "type": "patch",
+  },
+]
+`;
+
+exports[`workers/package/versions .determineUpgrades(npmDep, config) returns patch update if automerging patch 1`] = `
+Array [
+  Object {
+    "automergeEnabled": false,
+    "changeLogFromVersion": "0.9.0",
+    "changeLogToVersion": "1.4.1",
+    "isMajor": true,
+    "newVersion": "1.4.1",
+    "newVersionMajor": 1,
+    "newVersionMinor": 4,
+    "type": "major",
+  },
+  Object {
+    "automergeEnabled": true,
+    "changeLogFromVersion": "0.9.0",
+    "changeLogToVersion": "0.9.7",
+    "isPatch": true,
+    "newVersion": "0.9.7",
+    "newVersionMajor": 0,
+    "newVersionMinor": 9,
+    "type": "patch",
+  },
+]
+`;
+
+exports[`workers/package/versions .determineUpgrades(npmDep, config) returns patch update if separatePatchReleases 1`] = `
+Array [
+  Object {
+    "automergeEnabled": false,
+    "changeLogFromVersion": "0.9.0",
+    "changeLogToVersion": "1.4.1",
+    "isMajor": true,
+    "newVersion": "1.4.1",
+    "newVersionMajor": 1,
+    "newVersionMinor": 4,
+    "type": "major",
+  },
+  Object {
+    "automergeEnabled": false,
+    "changeLogFromVersion": "0.9.0",
+    "changeLogToVersion": "0.9.7",
+    "isPatch": true,
+    "newVersion": "0.9.7",
+    "newVersionMajor": 0,
+    "newVersionMinor": 9,
+    "type": "patch",
+  },
+]
+`;
+
 exports[`workers/package/versions .determineUpgrades(npmDep, config) should allow unstable versions if the current version is unstable 1`] = `
 Array [
   Object {
@@ -264,12 +349,12 @@ Array [
     "automergeEnabled": false,
     "changeLogFromVersion": "0.0.34",
     "changeLogToVersion": "0.0.35",
-    "isPatch": true,
+    "isMinor": true,
     "isRange": true,
     "newVersion": "^0.0.35",
     "newVersionMajor": 0,
     "newVersionMinor": 0,
-    "type": "patch",
+    "type": "minor",
   },
 ]
 `;
diff --git a/test/workers/package/index.spec.js b/test/workers/package/index.spec.js
index ac175021ce17b59872e37bf9f1313807418611d6..74d0793ec29de1d973893bbe89669f88ad3f6f27 100644
--- a/test/workers/package/index.spec.js
+++ b/test/workers/package/index.spec.js
@@ -53,5 +53,19 @@ describe('lib/workers/package/index', () => {
       expect(res).toHaveLength(1);
       expect(Object.keys(res[0])).toMatchSnapshot();
     });
+    it('merges type', async () => {
+      npmApi.getDependency.mockReturnValueOnce({});
+      versions.determineUpgrades = jest.fn(() => [
+        { isMajor: true },
+        { isMinor: true },
+        { isPatch: true },
+      ]);
+      const res = await pkgWorker.renovatePackage(config);
+      expect(res).toHaveLength(3);
+      expect(Object.keys(res[0])).toMatchSnapshot();
+      expect(res[0].branchName.indexOf('newVersionMinor')).toBe(-1);
+      expect(res[1].branchName.indexOf('newVersionMinor')).toBe(-1);
+      expect(res[2].branchName.indexOf('newVersionMinor')).not.toBe(-1);
+    });
   });
 });
diff --git a/test/workers/package/versions.spec.js b/test/workers/package/versions.spec.js
index e7fabd074497e134e04ac398e57ac0d7ba0a0f0f..09c3dee43472ee0b66f6b363acbd3b6e4d4716fe 100644
--- a/test/workers/package/versions.spec.js
+++ b/test/workers/package/versions.spec.js
@@ -49,11 +49,27 @@ describe('workers/package/versions', () => {
       config.currentVersion = '^0.4.0';
       expect(versions.determineUpgrades(qJson, config)).toMatchSnapshot();
     });
-    it('returns both updates if automerging patch', () => {
+    it('returns minor update if separate patches not configured', () => {
+      config.currentVersion = '0.9.0';
+      expect(versions.determineUpgrades(qJson, config)).toMatchSnapshot();
+    });
+    it('returns patch update if automerging patch', () => {
       config.automerge = 'patch';
       config.currentVersion = '0.9.0';
       expect(versions.determineUpgrades(qJson, config)).toMatchSnapshot();
     });
+    it('returns patch update if separatePatchReleases', () => {
+      config.separatePatchReleases = true;
+      config.currentVersion = '0.9.0';
+      expect(versions.determineUpgrades(qJson, config)).toMatchSnapshot();
+    });
+    it('returns patch minor and major', () => {
+      config.separatePatchReleases = true;
+      config.currentVersion = '0.8.0';
+      const res = versions.determineUpgrades(qJson, config);
+      expect(res).toHaveLength(3);
+      expect(res).toMatchSnapshot();
+    });
     it('disables major release separation (major)', () => {
       config.separateMajorReleases = false;
       config.currentVersion = '^0.4.0';