diff --git a/frontend/src/Settings/MediaManagement/MediaManagement.js b/frontend/src/Settings/MediaManagement/MediaManagement.js
index e33991ddf..77e956458 100644
--- a/frontend/src/Settings/MediaManagement/MediaManagement.js
+++ b/frontend/src/Settings/MediaManagement/MediaManagement.js
@@ -25,6 +25,12 @@ const rescanAfterRefreshOptions = [
   { key: 'never', value: 'Never' }
 ];
 
+const downloadPropersAndRepacksOptions = [
+  { key: 'preferAndUpgrade', value: 'Prefer and Upgrade' },
+  { key: 'doNotUpgrade', value: 'Do not Upgrade Automatically' },
+  { key: 'doNotPrefer', value: 'Do not Prefer' }
+];
+
 const fileDateOptions = [
   { key: 'none', value: 'None' },
   { key: 'localAirDate', value: 'Local Air Date' },
@@ -227,14 +233,23 @@ class MediaManagement extends Component {
                     isAdvanced={true}
                     size={sizes.MEDIUM}
                   >
-                    <FormLabel>Download Propers</FormLabel>
+                    <FormLabel>Propers and Repacks</FormLabel>
 
                     <FormInputGroup
-                      type={inputTypes.CHECK}
-                      name="autoDownloadPropers"
-                      helpText="Should Sonarr automatically upgrade to propers when available?"
+                      type={inputTypes.SELECT}
+                      name="downloadPropersAndRepacks"
+                      helpTexts={[
+                        'Whether or not to automatically upgrade to Propers/Repacks',
+                        'Use \'Do not Prefer\' to sort by preferred word score over propers/repacks'
+                      ]}
+                      helpTextWarning={
+                        settings.downloadPropersAndRepacks.value === 'doNotPrefer' ?
+                          'Use preferred words for automatic upgrades to propers/repacks' :
+                          undefined
+                      }
+                      values={downloadPropersAndRepacksOptions}
                       onChange={onInputChange}
-                      {...settings.autoDownloadPropers}
+                      {...settings.downloadPropersAndRepacks}
                     />
                   </FormGroup>
 
diff --git a/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs b/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs
index 0593f33b3..1992f8d5e 100644
--- a/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs
+++ b/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs
@@ -1,6 +1,7 @@
 using Sonarr.Http.REST;
 using NzbDrone.Core.Configuration;
 using NzbDrone.Core.MediaFiles;
+using NzbDrone.Core.Qualities;
 
 namespace NzbDrone.Api.Config
 {
@@ -8,7 +9,7 @@ namespace NzbDrone.Api.Config
     {
         public bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
         public string RecycleBin { get; set; }
-        public bool AutoDownloadPropers { get; set; }
+        public ProperDownloadTypes DownloadPropersAndRepacks { get; set; }
         public bool CreateEmptySeriesFolders { get; set; }
         public bool DeleteEmptyFolders { get; set; }
         public FileDateType FileDate { get; set; }
@@ -34,7 +35,7 @@ namespace NzbDrone.Api.Config
             {
                 AutoUnmonitorPreviouslyDownloadedEpisodes = model.AutoUnmonitorPreviouslyDownloadedEpisodes,
                 RecycleBin = model.RecycleBin,
-                AutoDownloadPropers = model.AutoDownloadPropers,
+                DownloadPropersAndRepacks = model.DownloadPropersAndRepacks,
                 CreateEmptySeriesFolders = model.CreateEmptySeriesFolders,
                 DeleteEmptyFolders = model.DeleteEmptyFolders,
                 FileDate = model.FileDate,
diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/PrioritizeDownloadDecisionFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/PrioritizeDownloadDecisionFixture.cs
index 493b12af3..5de93f33f 100644
--- a/src/NzbDrone.Core.Test/DecisionEngineTests/PrioritizeDownloadDecisionFixture.cs
+++ b/src/NzbDrone.Core.Test/DecisionEngineTests/PrioritizeDownloadDecisionFixture.cs
@@ -13,6 +13,7 @@ using NUnit.Framework;
 using FluentAssertions;
 using FizzWare.NBuilder;
 using NzbDrone.Common.Extensions;
+using NzbDrone.Core.Configuration;
 using NzbDrone.Core.Test.Framework;
 using NzbDrone.Core.Languages;
 using NzbDrone.Core.Profiles.Languages;
@@ -440,7 +441,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
         }
 
         [Test]
-        public void should_put_higher_quality_before_lower_allways()
+        public void should_put_higher_quality_before_lower_always()
         {
             var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.SDTV), Language.French);
             var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), Language.German);
@@ -452,5 +453,87 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
             var qualifiedReports = Subject.PrioritizeDecisions(decisions);
             qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Quality.Should().Be(Quality.HDTV720p);
         }
+
+        [Test]
+        public void should_prefer_higher_score_over_lower_score()
+        {
+            var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p), Language.English);
+            var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p), Language.English);
+
+            remoteEpisode1.PreferredWordScore = 10;
+            remoteEpisode2.PreferredWordScore = 0;
+
+            var decisions = new List<DownloadDecision>();
+            decisions.Add(new DownloadDecision(remoteEpisode1));
+            decisions.Add(new DownloadDecision(remoteEpisode2));
+
+            var qualifiedReports = Subject.PrioritizeDecisions(decisions);
+            qualifiedReports.First().RemoteEpisode.PreferredWordScore.Should().Be(10);
+        }
+
+        [Test]
+        public void should_prefer_proper_over_score_when_download_propers_is_prefer_and_upgrade()
+        {
+            Mocker.GetMock<IConfigService>()
+                  .Setup(s => s.DownloadPropersAndRepacks)
+                  .Returns(ProperDownloadTypes.PreferAndUpgrade);
+
+            var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(1)), Language.English);
+            var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(2)), Language.English);
+
+            remoteEpisode1.PreferredWordScore = 10;
+            remoteEpisode2.PreferredWordScore = 0;
+
+            var decisions = new List<DownloadDecision>();
+            decisions.Add(new DownloadDecision(remoteEpisode1));
+            decisions.Add(new DownloadDecision(remoteEpisode2));
+
+            var qualifiedReports = Subject.PrioritizeDecisions(decisions);
+            qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version.Should().Be(2);
+        }
+
+        [Test]
+        public void should_prefer_proper_over_score_when_download_propers_is_do_not_upgrade()
+        {
+            Mocker.GetMock<IConfigService>()
+                  .Setup(s => s.DownloadPropersAndRepacks)
+                  .Returns(ProperDownloadTypes.DoNotUpgrade);
+
+            var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(1)), Language.English);
+            var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(2)), Language.English);
+
+            remoteEpisode1.PreferredWordScore = 10;
+            remoteEpisode2.PreferredWordScore = 0;
+
+            var decisions = new List<DownloadDecision>();
+            decisions.Add(new DownloadDecision(remoteEpisode1));
+            decisions.Add(new DownloadDecision(remoteEpisode2));
+
+            var qualifiedReports = Subject.PrioritizeDecisions(decisions);
+            qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version.Should().Be(2);
+        }
+
+        [Test]
+        public void should_prefer_score_over_proper_when_download_propers_is_do_not_prefer()
+        {
+            Mocker.GetMock<IConfigService>()
+                  .Setup(s => s.DownloadPropersAndRepacks)
+                  .Returns(ProperDownloadTypes.DoNotPrefer);
+
+            var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(1)), Language.English);
+            var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(2)), Language.English);
+
+            remoteEpisode1.PreferredWordScore = 10;
+            remoteEpisode2.PreferredWordScore = 0;
+
+            var decisions = new List<DownloadDecision>();
+            decisions.Add(new DownloadDecision(remoteEpisode1));
+            decisions.Add(new DownloadDecision(remoteEpisode2));
+
+            var qualifiedReports = Subject.PrioritizeDecisions(decisions);
+            qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Quality.Should().Be(Quality.WEBDL1080p);
+            qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version.Should().Be(1);
+            qualifiedReports.First().RemoteEpisode.PreferredWordScore.Should().Be(10);
+        }
     }
 }
diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs
index cb8f3f663..5204cf715 100644
--- a/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs
+++ b/src/NzbDrone.Core.Test/DecisionEngineTests/RssSync/ProperSpecificationFixture.cs
@@ -11,7 +11,6 @@ using NzbDrone.Core.Parser.Model;
 using NzbDrone.Core.Profiles.Qualities;
 using NzbDrone.Core.Qualities;
 using NzbDrone.Core.Tv;
-using NzbDrone.Core.DecisionEngine;
 using NzbDrone.Core.DecisionEngine.Specifications;
 using NzbDrone.Core.Test.Framework;
 
@@ -61,13 +60,6 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
             _firstFile.Quality = new QualityModel(Quality.SDTV);
         }
 
-        private void GivenAutoDownloadPropers()
-        {
-            Mocker.GetMock<IConfigService>()
-                  .Setup(s => s.AutoDownloadPropers)
-                  .Returns(true);
-        }
-
         [Test]
         public void should_return_false_when_episodeFile_was_added_more_than_7_days_ago()
         {
@@ -118,6 +110,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
         [Test]
         public void should_return_false_when_proper_but_auto_download_propers_is_false()
         {
+            Mocker.GetMock<IConfigService>()
+                  .Setup(s => s.DownloadPropersAndRepacks)
+                  .Returns(ProperDownloadTypes.DoNotUpgrade);
+
             _firstFile.Quality.Quality = Quality.DVD;
 
             _firstFile.DateAdded = DateTime.Today;
@@ -127,7 +123,22 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
         [Test]
         public void should_return_true_when_episodeFile_was_added_today()
         {
-            GivenAutoDownloadPropers();
+            Mocker.GetMock<IConfigService>()
+                  .Setup(s => s.DownloadPropersAndRepacks)
+                  .Returns(ProperDownloadTypes.PreferAndUpgrade);
+
+            _firstFile.Quality.Quality = Quality.DVD;
+
+            _firstFile.DateAdded = DateTime.Today;
+            Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue();
+        }
+
+        [Test]
+        public void should_return_true_when_propers_are_not_preferred()
+        {
+            Mocker.GetMock<IConfigService>()
+                  .Setup(s => s.DownloadPropersAndRepacks)
+                  .Returns(ProperDownloadTypes.DoNotPrefer);
 
             _firstFile.Quality.Quality = Quality.DVD;
 
diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs
index 786df4a4f..e8383a0db 100644
--- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs
+++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs
@@ -38,17 +38,17 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
 
         private static readonly int NoPreferredWordScore = 0;
 
-        private void GivenAutoDownloadPropers(bool autoDownloadPropers)
+        private void GivenAutoDownloadPropers(ProperDownloadTypes type)
         {
             Mocker.GetMock<IConfigService>()
-                  .SetupGet(s => s.AutoDownloadPropers)
-                  .Returns(autoDownloadPropers);
+                  .SetupGet(s => s.DownloadPropersAndRepacks)
+                  .Returns(type);
         }
 
         [Test, TestCaseSource(nameof(IsUpgradeTestCases))]
         public void IsUpgradeTest(Quality current, int currentVersion, Quality newQuality, int newVersion, Quality cutoff, bool expected)
         {
-            GivenAutoDownloadPropers(true);
+            GivenAutoDownloadPropers(ProperDownloadTypes.PreferAndUpgrade);
 
 
             var profile = new QualityProfile
@@ -79,7 +79,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
         [Test, TestCaseSource("IsUpgradeTestCasesLanguages")]
         public void IsUpgradeTestLanguage(Quality current, int currentVersion, Language currentLanguage, Quality newQuality, int newVersion, Language newLanguage, Quality cutoff, Language languageCutoff, bool expected)
         {
-            GivenAutoDownloadPropers(true);
+            GivenAutoDownloadPropers(ProperDownloadTypes.PreferAndUpgrade);
 
             var profile = new QualityProfile
             {
@@ -108,9 +108,9 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
         }
 
         [Test]
-        public void should_return_false_if_proper_and_autoDownloadPropers_is_false()
+        public void should_return_true_if_proper_and_download_propers_is_do_not_download()
         {
-            GivenAutoDownloadPropers(false);
+            GivenAutoDownloadPropers(ProperDownloadTypes.DoNotUpgrade);
 
             var profile = new QualityProfile 
             { 
@@ -127,13 +127,42 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
             Subject.IsUpgradable(
                        profile,
                        langProfile,
-                       new QualityModel(Quality.DVD, new Revision(version: 2)),
-                       Language.English,
-                       NoPreferredWordScore,
                        new QualityModel(Quality.DVD, new Revision(version: 1)),
                        Language.English,
+                       NoPreferredWordScore,
+                       new QualityModel(Quality.DVD, new Revision(version: 2)),
+                       Language.English,
                        NoPreferredWordScore)
-                    .Should().BeFalse();
+                    .Should().BeTrue();
+        }
+
+        [Test]
+        public void should_return_false_if_proper_and_autoDownloadPropers_is_do_not_prefer()
+        {
+            GivenAutoDownloadPropers(ProperDownloadTypes.DoNotPrefer);
+
+            var profile = new QualityProfile
+                          {
+                              Items = Qualities.QualityFixture.GetDefaultQualities(),
+                          };
+
+            var langProfile = new LanguageProfile
+                              {
+                                  Languages = LanguageFixture.GetDefaultLanguages(),
+                                  Cutoff = Language.English
+                              };
+
+
+            Subject.IsUpgradable(
+                       profile,
+                       langProfile,
+                       new QualityModel(Quality.DVD, new Revision(version: 1)),
+                       Language.English,
+                       NoPreferredWordScore,
+                       new QualityModel(Quality.DVD, new Revision(version: 2)),
+                       Language.English,
+                       NoPreferredWordScore)
+                   .Should().BeFalse();
         }
     }
 }
diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs
index beabaa284..bf6c1ed1d 100644
--- a/src/NzbDrone.Core/Configuration/ConfigService.cs
+++ b/src/NzbDrone.Core/Configuration/ConfigService.cs
@@ -9,6 +9,7 @@ using NzbDrone.Core.MediaFiles;
 using NzbDrone.Core.Messaging.Events;
 using NzbDrone.Common.Http.Proxy;
 using NzbDrone.Core.MediaFiles.EpisodeImport;
+using NzbDrone.Core.Qualities;
 using NzbDrone.Core.Security;
 
 namespace NzbDrone.Core.Configuration
@@ -113,11 +114,11 @@ namespace NzbDrone.Core.Configuration
             set { SetValue("MinimumAge", value); }
         }
 
-        public bool AutoDownloadPropers
+        public ProperDownloadTypes DownloadPropersAndRepacks
         {
-            get { return GetValueBoolean("AutoDownloadPropers", true); }
+            get { return GetValueEnum("DownloadPropersAndRepacks", ProperDownloadTypes.PreferAndUpgrade); }
 
-            set { SetValue("AutoDownloadPropers", value); }
+            set { SetValue("DownloadPropersAndRepacks", value); }
         }
 
         public bool EnableCompletedDownloadHandling
diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs
index 80d18b2f8..a16b64f76 100644
--- a/src/NzbDrone.Core/Configuration/IConfigService.cs
+++ b/src/NzbDrone.Core/Configuration/IConfigService.cs
@@ -2,6 +2,7 @@ using System.Collections.Generic;
 using NzbDrone.Core.MediaFiles;
 using NzbDrone.Common.Http.Proxy;
 using NzbDrone.Core.MediaFiles.EpisodeImport;
+using NzbDrone.Core.Qualities;
 using NzbDrone.Core.Security;
 
 namespace NzbDrone.Core.Configuration
@@ -26,7 +27,7 @@ namespace NzbDrone.Core.Configuration
         //Media Management
         bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
         string RecycleBin { get; set; }
-        bool AutoDownloadPropers { get; set; }
+        ProperDownloadTypes DownloadPropersAndRepacks { get; set; }
         bool CreateEmptySeriesFolders { get; set; }
         bool DeleteEmptyFolders { get; set; }
         FileDateType FileDate { get; set; }
diff --git a/src/NzbDrone.Core/Datastore/Migration/131_download_propers_config.cs b/src/NzbDrone.Core/Datastore/Migration/131_download_propers_config.cs
new file mode 100644
index 000000000..fdf1a363b
--- /dev/null
+++ b/src/NzbDrone.Core/Datastore/Migration/131_download_propers_config.cs
@@ -0,0 +1,43 @@
+using System.Data;
+using FluentMigrator;
+using NzbDrone.Core.Datastore.Migration.Framework;
+
+namespace NzbDrone.Core.Datastore.Migration
+{
+    [Migration(131)]
+    public class download_propers_config : NzbDroneMigrationBase
+    {
+        protected override void MainDbUpgrade()
+        {
+            Execute.WithConnection(SetMetadataFileExtension);
+            Execute.Sql("DELETE FROM Config WHERE Key = 'autodownloadpropers'");
+        }
+
+        private void SetMetadataFileExtension(IDbConnection conn, IDbTransaction tran)
+        {
+            using (var cmd = conn.CreateCommand())
+            {
+                cmd.Transaction = tran;
+                cmd.CommandText = "SELECT Value FROM Config WHERE Key = 'autodownloadpropers'";
+
+                using (var reader = cmd.ExecuteReader())
+                {
+                    while (reader.Read())
+                    {
+                        var value = reader.GetString(0);
+                        var newValue = bool.Parse(value) ? "PreferAndUpgrade" : "DoNotUpgrade";
+
+                        using (var updateCmd = conn.CreateCommand())
+                        {
+                            updateCmd.Transaction = tran;
+                            updateCmd.CommandText = "INSERT INTO Config (key, value) VALUES ('downloadpropersandrepacks', ?)";
+                            updateCmd.AddParameter(newValue);
+
+                            updateCmd.ExecuteNonQuery();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs
index 5f57800c0..b1dc83189 100644
--- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs
+++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs
@@ -1,21 +1,26 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using NzbDrone.Core.Configuration;
 using NzbDrone.Core.Indexers;
 using NzbDrone.Core.Parser.Model;
 using NzbDrone.Core.Profiles.Delay;
+using NzbDrone.Core.Qualities;
 using NzbDrone.Core.Tv;
 
 namespace NzbDrone.Core.DecisionEngine
 {
     public class DownloadDecisionComparer : IComparer<DownloadDecision>
     {
+        private readonly IConfigService _configService;
         private readonly IDelayProfileService _delayProfileService;
+
         public delegate int CompareDelegate(DownloadDecision x, DownloadDecision y);
         public delegate int CompareDelegate<TSubject, TValue>(DownloadDecision x, DownloadDecision y);
 
-        public DownloadDecisionComparer(IDelayProfileService delayProfileService)
+        public DownloadDecisionComparer(IConfigService configService, IDelayProfileService delayProfileService)
         {
+            _configService = configService;
             _delayProfileService = delayProfileService;
         }
 
@@ -59,6 +64,12 @@ namespace NzbDrone.Core.DecisionEngine
 
         private int CompareQuality(DownloadDecision x, DownloadDecision y)
         {
+            if (_configService.DownloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer)
+            {
+                return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Series.QualityProfile.Value.GetIndex(remoteEpisode.ParsedEpisodeInfo.Quality.Quality)),
+                    CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Real));
+            }
+
             return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Series.QualityProfile.Value.GetIndex(remoteEpisode.ParsedEpisodeInfo.Quality.Quality)),
                            CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Real),
                            CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version));
diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionPriorizationService.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionPriorizationService.cs
index 344c7544c..ce3365471 100644
--- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionPriorizationService.cs
+++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionPriorizationService.cs
@@ -1,7 +1,7 @@
 using System.Linq;
 using System.Collections.Generic;
+using NzbDrone.Core.Configuration;
 using NzbDrone.Core.Profiles.Delay;
-using NzbDrone.Core.Languages;
 
 namespace NzbDrone.Core.DecisionEngine
 {
@@ -12,10 +12,12 @@ namespace NzbDrone.Core.DecisionEngine
 
     public class DownloadDecisionPriorizationService : IPrioritizeDownloadDecision
     {
+        private readonly IConfigService _configService;
         private readonly IDelayProfileService _delayProfileService;
 
-        public DownloadDecisionPriorizationService(IDelayProfileService delayProfileService)
+        public DownloadDecisionPriorizationService(IConfigService configService, IDelayProfileService delayProfileService)
         {
+            _configService = configService;
             _delayProfileService = delayProfileService;
         }
 
@@ -24,7 +26,7 @@ namespace NzbDrone.Core.DecisionEngine
             return decisions.Where(c => c.RemoteEpisode.Series != null)
                             .GroupBy(c => c.RemoteEpisode.Series.Id, (seriesId, downloadDecisions) =>
                                 {
-                                    return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService));
+                                    return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_configService, _delayProfileService));
                                 })
                             .SelectMany(c => c)
                             .Union(decisions.Where(c => c.RemoteEpisode.Series == null))
diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs
index 163fbea84..d2e843c90 100644
--- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs
+++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs
@@ -4,6 +4,7 @@ using NLog;
 using NzbDrone.Core.Configuration;
 using NzbDrone.Core.IndexerSearch.Definitions;
 using NzbDrone.Core.Parser.Model;
+using NzbDrone.Core.Qualities;
 
 namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
 {
@@ -30,21 +31,29 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
                 return Decision.Accept();
             }
 
+            var downloadPropersAndRepacks = _configService.DownloadPropersAndRepacks;
+
+            if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer)
+            {
+                _logger.Debug("Propers are not preferred, skipping check");
+                return Decision.Accept();
+            }
+
             foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value))
             {
                 if (_upgradableSpecification.IsRevisionUpgrade(file.Quality, subject.ParsedEpisodeInfo.Quality))
                 {
+                    if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotUpgrade)
+                    {
+                        _logger.Debug("Auto downloading of propers is disabled");
+                        return Decision.Reject("Proper downloading is disabled");
+                    }
+
                     if (file.DateAdded < DateTime.Today.AddDays(-7))
                     {
                         _logger.Debug("Proper for old file, rejecting: {0}", subject);
                         return Decision.Reject("Proper for old file");
                     }
-
-                    if (!_configService.AutoDownloadPropers)
-                    {
-                        _logger.Debug("Auto downloading of propers is disabled");
-                        return Decision.Reject("Proper downloading is disabled");
-                    }
                 }
             }
 
diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs
index 82656a2cc..a278d0b09 100644
--- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs
+++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs
@@ -1,4 +1,5 @@
 using NLog;
+using NzbDrone.Core.Configuration;
 using NzbDrone.Core.Languages;
 using NzbDrone.Core.Profiles.Languages;
 using NzbDrone.Core.Profiles.Qualities;
@@ -18,41 +19,15 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
 
     public class UpgradableSpecification : IUpgradableSpecification
     {
+        private readonly IConfigService _configService;
         private readonly Logger _logger;
 
-        public UpgradableSpecification(Logger logger)
+        public UpgradableSpecification(IConfigService configService, Logger logger)
         {
+            _configService = configService;
             _logger = logger;
         }
 
-        private bool IsLanguageUpgradable(LanguageProfile profile, Language currentLanguage, Language newLanguage = null) 
-        {
-            if (newLanguage != null)
-            {
-                var compare = new LanguageComparer(profile).Compare(newLanguage, currentLanguage);
-                if (compare <= 0)
-                {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private bool IsQualityUpgradable(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
-        {
-            if (newQuality != null)
-            {
-                var compare = new QualityModelComparer(profile).Compare(newQuality, currentQuality);
-
-                if (compare <= 0)
-                {
-                    _logger.Debug("Existing item has better quality, skipping");
-                    return false;
-                }
-            }
-            return true;
-        }
-
         private bool IsPreferredWordUpgradable(int currentScore, int newScore)
         {
             return newScore > currentScore;
@@ -60,23 +35,36 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
 
         public bool IsUpgradable(QualityProfile qualityProfile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality, Language newLanguage, int newScore)
         {
-            if (IsQualityUpgradable(qualityProfile, currentQuality, newQuality))
+            var qualityComparer = new QualityModelComparer(qualityProfile);
+            var qualityCompare = qualityComparer.Compare(newQuality?.Quality, currentQuality.Quality);
+
+            if (qualityCompare > 0)
             {
                 return true;
             }
 
-            if (new QualityModelComparer(qualityProfile).Compare(newQuality, currentQuality) < 0)
+            if (qualityCompare < 0)
             {
                 _logger.Debug("Existing item has better quality, skipping");
                 return false;
             }
 
-            if (IsLanguageUpgradable(languageProfile, currentLanguage, newLanguage))
+            // Accept unless the user doesn't want to prefer propers, optionally they can
+            // use preferred words to prefer propers/repacks over non-propers/repacks.
+            if (_configService.DownloadPropersAndRepacks != ProperDownloadTypes.DoNotPrefer &&
+                newQuality?.Revision.CompareTo(currentQuality.Revision) > 0)
             {
                 return true;
             }
 
-            if (new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage) < 0)
+            var languageCompare = new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage);
+
+            if (languageCompare > 0)
+            {
+                return true;
+            }
+
+            if (languageCompare < 0)
             {
                 _logger.Debug("Existing item has better language, skipping");
                 return false;
diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj
index 5c3ea3dc0..dce02434c 100644
--- a/src/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/src/NzbDrone.Core/NzbDrone.Core.csproj
@@ -136,6 +136,7 @@
     <Compile Include="Configuration\InvalidConfigFileException.cs" />
     <Compile Include="Configuration\RescanAfterRefreshType.cs" />
     <Compile Include="Configuration\ResetApiKeyCommand.cs" />
+    <Compile Include="Datastore\Migration\131_download_propers_config.cs" />
     <Compile Include="Datastore\Migration\130_episode_last_searched_time.cs" />
     <Compile Include="Datastore\Migration\129_add_relative_original_path_to_episode_file.cs" />
     <Compile Include="Datastore\Migration\128_rename_quality_profiles_add_upgrade_allowed.cs" />
@@ -1034,6 +1035,7 @@
     <Compile Include="Profiles\Releases\TermMatchers\ITermMatcher.cs" />
     <Compile Include="Profiles\Releases\TermMatchers\RegexTermMatcher.cs" />
     <Compile Include="ProgressMessaging\ProgressMessageContext.cs" />
+    <Compile Include="Qualities\ProperDownloadTypes.cs" />
     <Compile Include="Qualities\QualityDetectionSource.cs" />
     <Compile Include="Qualities\QualityFinder.cs" />
     <Compile Include="Qualities\QualitySource.cs" />
diff --git a/src/NzbDrone.Core/Qualities/ProperDownloadTypes.cs b/src/NzbDrone.Core/Qualities/ProperDownloadTypes.cs
new file mode 100644
index 000000000..1620d75ff
--- /dev/null
+++ b/src/NzbDrone.Core/Qualities/ProperDownloadTypes.cs
@@ -0,0 +1,9 @@
+namespace NzbDrone.Core.Qualities
+{
+    public enum ProperDownloadTypes
+    {
+        PreferAndUpgrade,
+        DoNotUpgrade,
+        DoNotPrefer
+    }
+}
diff --git a/src/Sonarr.Api.V3/Config/MediaManagementConfigResource.cs b/src/Sonarr.Api.V3/Config/MediaManagementConfigResource.cs
index e47578501..338c9e282 100644
--- a/src/Sonarr.Api.V3/Config/MediaManagementConfigResource.cs
+++ b/src/Sonarr.Api.V3/Config/MediaManagementConfigResource.cs
@@ -1,6 +1,7 @@
 using NzbDrone.Core.Configuration;
 using NzbDrone.Core.MediaFiles;
 using NzbDrone.Core.MediaFiles.EpisodeImport;
+using NzbDrone.Core.Qualities;
 using Sonarr.Http.REST;
 
 namespace Sonarr.Api.V3.Config
@@ -9,7 +10,7 @@ namespace Sonarr.Api.V3.Config
     {
         public bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
         public string RecycleBin { get; set; }
-        public bool AutoDownloadPropers { get; set; }
+        public ProperDownloadTypes DownloadPropersAndRepacks { get; set; }
         public bool CreateEmptySeriesFolders { get; set; }
         public bool DeleteEmptyFolders { get; set; }
         public FileDateType FileDate { get; set; }
@@ -37,7 +38,7 @@ namespace Sonarr.Api.V3.Config
             {
                 AutoUnmonitorPreviouslyDownloadedEpisodes = model.AutoUnmonitorPreviouslyDownloadedEpisodes,
                 RecycleBin = model.RecycleBin,
-                AutoDownloadPropers = model.AutoDownloadPropers,
+                DownloadPropersAndRepacks = model.DownloadPropersAndRepacks,
                 CreateEmptySeriesFolders = model.CreateEmptySeriesFolders,
                 DeleteEmptyFolders = model.DeleteEmptyFolders,
                 FileDate = model.FileDate,