diff --git a/Cabal/Distribution/Simple.hs b/Cabal/Distribution/Simple.hs
index e45c8312ac5cc25f5343faa5b21a90556bc3cfad..4d348d94983e78f3d21f6f7d905758e279f40312 100644
--- a/Cabal/Distribution/Simple.hs
+++ b/Cabal/Distribution/Simple.hs
@@ -329,7 +329,7 @@ haddockAction hooks flags args = do
 
   hookedAction preHaddock haddockHook postHaddock
                (return lbi { withPrograms = progs })
-               hooks flags' args
+               hooks flags' { haddockArgs = args } args
 
 cleanAction :: UserHooks -> CleanFlags -> Args -> IO ()
 cleanAction hooks flags args = do
diff --git a/Cabal/Distribution/Simple/Haddock.hs b/Cabal/Distribution/Simple/Haddock.hs
index 0a40a877712a3d11f56f38e32aec784b7a6c7667..afbd59c9dfc835536898eea6b8970b190e5183ba 100644
--- a/Cabal/Distribution/Simple/Haddock.hs
+++ b/Cabal/Distribution/Simple/Haddock.hs
@@ -36,6 +36,8 @@ import Distribution.Types.ForeignLib
 import Distribution.Types.UnqualComponentName
 import Distribution.Types.ComponentLocalBuildInfo
 import Distribution.Types.ExecutableScope
+import Distribution.Types.LocalBuildInfo
+import Distribution.Types.TargetInfo
 import Distribution.Package
 import qualified Distribution.ModuleName as ModuleName
 import Distribution.PackageDescription as PD hiding (Flag)
@@ -46,6 +48,7 @@ import Distribution.Simple.Program
 import Distribution.Simple.PreProcess
 import Distribution.Simple.Setup
 import Distribution.Simple.Build
+import Distribution.Simple.BuildTarget
 import Distribution.Simple.InstallDirs
 import Distribution.Simple.LocalBuildInfo hiding (substPathTemplate)
 import Distribution.Simple.BuildPaths
@@ -199,7 +202,18 @@ haddock pkg_descr lbi suffixes flags' = do
             , fromFlags (haddockTemplateEnv lbi (packageId pkg_descr)) flags
             , fromPackageDescription haddockTarget pkg_descr ]
 
-    withAllComponentsInBuildOrder pkg_descr lbi $ \component clbi -> do
+    targets <- readTargetInfos verbosity pkg_descr lbi (haddockArgs flags)
+
+    let
+      targets' =
+        case targets of
+          [] -> allTargetsInBuildOrder' pkg_descr lbi
+          _  -> targets
+
+    for_ targets' $ \target -> do
+      let component = targetComponent target
+          clbi      = targetCLBI target
+
       componentInitialBuildSteps (flag haddockDistPref) pkg_descr lbi clbi verbosity
       preprocessComponent pkg_descr component lbi clbi False verbosity suffixes
       let
diff --git a/Cabal/Distribution/Simple/Setup.hs b/Cabal/Distribution/Simple/Setup.hs
index 5fa0e993a734f392efded27bd9bea780cd7d7b7d..241883b7fbfa526d0155377876e3fc67db245a77 100644
--- a/Cabal/Distribution/Simple/Setup.hs
+++ b/Cabal/Distribution/Simple/Setup.hs
@@ -1470,7 +1470,8 @@ data HaddockFlags = HaddockFlags {
     haddockDistPref     :: Flag FilePath,
     haddockKeepTempFiles:: Flag Bool,
     haddockVerbosity    :: Flag Verbosity,
-    haddockCabalFilePath :: Flag FilePath
+    haddockCabalFilePath :: Flag FilePath,
+    haddockArgs         :: [String]
   }
   deriving (Show, Generic)
 
@@ -1494,7 +1495,8 @@ defaultHaddockFlags  = HaddockFlags {
     haddockDistPref     = NoFlag,
     haddockKeepTempFiles= Flag False,
     haddockVerbosity    = Flag normal,
-    haddockCabalFilePath = mempty
+    haddockCabalFilePath = mempty,
+    haddockArgs         = mempty
   }
 
 haddockCommand :: CommandUI HaddockFlags
@@ -1504,8 +1506,10 @@ haddockCommand = CommandUI
   , commandDescription  = Just $ \_ ->
       "Requires the program haddock, version 2.x.\n"
   , commandNotes        = Nothing
-  , commandUsage        = \pname ->
-      "Usage: " ++ pname ++ " haddock [FLAGS]\n"
+  , commandUsage        = usageAlternatives "haddock" $
+      [ "[FLAGS]"
+      , "COMPONENTS [FLAGS]"
+      ]
   , commandDefaultFlags = defaultHaddockFlags
   , commandOptions      = \showOrParseArgs ->
          haddockOptions showOrParseArgs
diff --git a/Cabal/Distribution/Simple/UserHooks.hs b/Cabal/Distribution/Simple/UserHooks.hs
index 31e9cd66aea1e9e939bb62ed5aaa9ecfe085f734..56f91dc20a6e7a86bbc93dc6075f4d9c7da3def2 100644
--- a/Cabal/Distribution/Simple/UserHooks.hs
+++ b/Cabal/Distribution/Simple/UserHooks.hs
@@ -207,7 +207,7 @@ emptyUserHooks
       preDoctest   = rn,
       doctestHook  = ru,
       postDoctest  = ru,
-      preHaddock   = rn,
+      preHaddock   = rn',
       haddockHook  = ru,
       postHaddock  = ru,
       preTest  = rn',
diff --git a/cabal-install/Distribution/Client/Config.hs b/cabal-install/Distribution/Client/Config.hs
index 97b9c6dcaa30a42ed4253b5eb97ce070730ac419..b114e003002b0cb7807538491dbb373ec5417981 100644
--- a/cabal-install/Distribution/Client/Config.hs
+++ b/cabal-install/Distribution/Client/Config.hs
@@ -413,7 +413,8 @@ instance Semigroup SavedConfig where
         haddockDistPref      = combine haddockDistPref,
         haddockKeepTempFiles = combine haddockKeepTempFiles,
         haddockVerbosity     = combine haddockVerbosity,
-        haddockCabalFilePath = combine haddockCabalFilePath
+        haddockCabalFilePath = combine haddockCabalFilePath,
+        haddockArgs          = lastNonEmpty haddockArgs
         }
         where
           combine      = combine'        savedHaddockFlags
diff --git a/cabal-install/Distribution/Client/ProjectBuilding.hs b/cabal-install/Distribution/Client/ProjectBuilding.hs
index 10a2a93df03ba7ebc113938f46000a54e5ab11d6..24c28151464b54e12bf40f2b727023933a70fea3 100644
--- a/cabal-install/Distribution/Client/ProjectBuilding.hs
+++ b/cabal-install/Distribution/Client/ProjectBuilding.hs
@@ -366,11 +366,12 @@ packageFileMonitorKeyValues elab =
     --
     elab_config =
         elab {
-            elabBuildTargets  = [],
-            elabTestTargets   = [],
+            elabBuildTargets   = [],
+            elabTestTargets    = [],
             elabBenchTargets   = [],
-            elabReplTarget    = Nothing,
-            elabBuildHaddocks = False
+            elabReplTarget     = Nothing,
+            elabHaddockTargets = [],
+            elabBuildHaddocks  = False
         }
 
     -- The second part is the value used to guard the build step. So this is
@@ -1217,7 +1218,7 @@ buildInplaceUnpackedPackage verbosity
         -- Haddock phase
         whenHaddock $
           annotateFailureNoLog HaddocksFailed $ do
-            setup haddockCommand haddockFlags []
+            setup haddockCommand haddockFlags haddockArgs
             let haddockTarget = elabHaddockForHackage pkg
             when (haddockTarget == Cabal.ForHackage) $ do
               let dest = distDirectory </> name <.> "tar.gz"
@@ -1304,6 +1305,7 @@ buildInplaceUnpackedPackage verbosity
     haddockCommand   = Cabal.haddockCommand
     haddockFlags _   = setupHsHaddockFlags pkg pkgshared
                                            verbosity builddir
+    haddockArgs      = setupHsHaddockArgs pkg
 
     scriptOptions    = setupHsScriptOptions rpkg pkgshared
                                             srcdir builddir
diff --git a/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
index 4999740d1ca47925e4a139e17a7f156e182482d0..9a86104a3be175ca7156a839b2a792daf4804fc1 100644
--- a/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
+++ b/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
@@ -733,7 +733,8 @@ convertToLegacyPerPackageConfig PackageConfig {..} =
       haddockDistPref      = mempty,
       haddockKeepTempFiles = mempty,
       haddockVerbosity     = mempty,
-      haddockCabalFilePath = mempty
+      haddockCabalFilePath = mempty,
+      haddockArgs          = mempty
     }
 
 
diff --git a/cabal-install/Distribution/Client/ProjectPlanning.hs b/cabal-install/Distribution/Client/ProjectPlanning.hs
index a9fe664b44a52c6fc438a2967510f5e22b893f50..c597fea5237296e2226b3c887b6e8c067a8d8e25 100644
--- a/cabal-install/Distribution/Client/ProjectPlanning.hs
+++ b/cabal-install/Distribution/Client/ProjectPlanning.hs
@@ -56,6 +56,7 @@ module Distribution.Client.ProjectPlanning (
     setupHsCopyFlags,
     setupHsRegisterFlags,
     setupHsHaddockFlags,
+    setupHsHaddockArgs,
 
     packageHashInputs,
 
@@ -1727,6 +1728,8 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
         elabTestTargets     = []
         elabBenchTargets    = []
         elabReplTarget      = Nothing
+        elabHaddockTargets  = []
+
         elabBuildHaddocks   =
           perPkgOptionFlag pkgid False packageConfigDocumentation
 
@@ -2437,6 +2440,7 @@ pkgHasEphemeralBuildTargets elab =
     isJust (elabReplTarget elab)
  || (not . null) (elabTestTargets elab)
  || (not . null) (elabBenchTargets elab)
+ || (not . null) (elabHaddockTargets elab)
  || (not . null) [ () | ComponentTarget _ subtarget <- elabBuildTargets elab
                       , subtarget /= WholeComponent ]
 
@@ -2535,11 +2539,22 @@ setRootTargets targetAction perPkgTargetsMap =
         (Just tgts,  TargetActionBuild)   -> elab { elabBuildTargets = tgts }
         (Just tgts,  TargetActionTest)    -> elab { elabTestTargets  = tgts }
         (Just tgts,  TargetActionBench)   -> elab { elabBenchTargets  = tgts }
-        (Just [tgt], TargetActionRepl)    -> elab { elabReplTarget = Just tgt }
-        (Just _,     TargetActionHaddock) -> elab { elabBuildHaddocks = True }
+        (Just [tgt], TargetActionRepl)    -> elab { elabReplTarget = Just tgt
+                                                  , elabBuildHaddocks = False }
+        (Just tgts,  TargetActionHaddock) ->
+          foldr setElabHaddockTargets (elab { elabHaddockTargets = tgts
+                                            , elabBuildHaddocks = True }) tgts
         (Just _,     TargetActionRepl)    ->
           error "pruneInstallPlanToTargets: multiple repl targets"
 
+    setElabHaddockTargets tgt elab
+      | isTestComponentTarget tgt       = elab { elabHaddockTestSuites  = True }
+      | isBenchComponentTarget tgt      = elab { elabHaddockBenchmarks  = True }
+      | isForeignLibComponentTarget tgt = elab { elabHaddockForeignLibs = True }
+      | isExeComponentTarget tgt        = elab { elabHaddockExecutables = True }
+      | isSubLibComponentTarget tgt     = elab { elabHaddockInternal    = True }
+      | otherwise                       = elab
+
 -- | Assuming we have previously set the root build targets (i.e. the user
 -- targets but not rev deps yet), the first pruning pass does two things:
 --
@@ -2560,14 +2575,16 @@ pruneInstallPlanPass1 pkgs =
     roots = mapMaybe find_root pkgs'
 
     prune elab = PrunedPackage elab' (pruneOptionalDependencies elab')
-      where elab' = addOptionalStanzas elab
+      where elab' =
+                setDocumentation
+              $ addOptionalStanzas elab
 
     find_root (InstallPlan.Configured (PrunedPackage elab _)) =
         if not (null (elabBuildTargets elab)
                     && null (elabTestTargets elab)
                     && null (elabBenchTargets elab)
                     && isNothing (elabReplTarget elab)
-                    && not (elabBuildHaddocks elab))
+                    && null (elabHaddockTargets elab))
             then Just (installedUnitId elab)
             else Nothing
     find_root _ = Nothing
@@ -2613,6 +2630,26 @@ pruneInstallPlanPass1 pkgs =
                <> optionalStanzasWithDepsAvailable availablePkgs elab pkg
     addOptionalStanzas elab = elab
 
+    setDocumentation :: ElaboratedConfiguredPackage -> ElaboratedConfiguredPackage
+    setDocumentation elab@ElaboratedConfiguredPackage { elabPkgOrComp = ElabComponent comp } =
+      elab {
+        elabBuildHaddocks =
+            elabBuildHaddocks elab && documentationEnabled (compSolverName comp) elab
+      }
+
+      where
+        documentationEnabled c =
+          case c of
+            CD.ComponentLib      -> const True
+            CD.ComponentSubLib _ -> elabHaddockInternal
+            CD.ComponentFLib _   -> elabHaddockForeignLibs
+            CD.ComponentExe _    -> elabHaddockExecutables
+            CD.ComponentTest _   -> elabHaddockTestSuites
+            CD.ComponentBench _  -> elabHaddockBenchmarks
+            CD.ComponentSetup    -> const False
+
+    setDocumentation elab = elab
+
     -- Calculate package dependencies but cut out those needed only by
     -- optional stanzas that we've determined we will not enable.
     -- These pruned deps are not persisted in this pass since they're based on
@@ -3159,7 +3196,7 @@ setupHsConfigureFlags (ReadyPackage elab@ElaboratedConfiguredPackage{..})
     configVanillaLib          = toFlag elabVanillaLib
     configSharedLib           = toFlag elabSharedLib
     configStaticLib           = toFlag elabStaticLib
-    
+
     configDynExe              = toFlag elabDynExe
     configGHCiLib             = toFlag elabGHCiLib
     configProfExe             = mempty
@@ -3391,9 +3428,15 @@ setupHsHaddockFlags (ElaboratedConfiguredPackage{..}) _ verbosity builddir =
       haddockDistPref      = toFlag builddir,
       haddockKeepTempFiles = mempty, --TODO: from build settings
       haddockVerbosity     = toFlag verbosity,
-      haddockCabalFilePath = mempty
+      haddockCabalFilePath = mempty,
+      haddockArgs          = mempty
     }
 
+setupHsHaddockArgs :: ElaboratedConfiguredPackage -> [String]
+-- TODO: Does the issue #3335 affects test as well
+setupHsHaddockArgs elab =
+  map (showComponentTarget (packageId elab)) (elabHaddockTargets elab)
+
 {-
 setupHsTestFlags :: ElaboratedConfiguredPackage
                  -> ElaboratedSharedConfig
@@ -3582,4 +3625,3 @@ inplaceBinRoot
 inplaceBinRoot layout config package
   =  distBuildDirectory layout (elabDistDirParams config package)
  </> "build"
-
diff --git a/cabal-install/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/Distribution/Client/ProjectPlanning/Types.hs
index ef537cc41efec04abae7f9c6064d8cf115aa444a..138d76b52195ca8cab22388d82515f83971e7674 100644
--- a/cabal-install/Distribution/Client/ProjectPlanning/Types.hs
+++ b/cabal-install/Distribution/Client/ProjectPlanning/Types.hs
@@ -45,7 +45,11 @@ module Distribution.Client.ProjectPlanning.Types (
     showBenchComponentTarget,
     SubComponentTarget(..),
 
+    isSubLibComponentTarget,
+    isForeignLibComponentTarget,
+    isExeComponentTarget,
     isTestComponentTarget,
+    isBenchComponentTarget,
 
     -- * Setup script
     SetupScriptStyle(..),
@@ -289,6 +293,8 @@ data ElaboratedConfiguredPackage
        elabTestTargets           :: [ComponentTarget],
        elabBenchTargets          :: [ComponentTarget],
        elabReplTarget            :: Maybe ComponentTarget,
+       elabHaddockTargets        :: [ComponentTarget],
+
        elabBuildHaddocks         :: Bool,
 
        --pkgSourceDir ? -- currently passed in later because they can use temp locations
@@ -667,6 +673,22 @@ showBenchComponentTarget :: PackageId -> ComponentTarget -> Maybe String
 showBenchComponentTarget _ (ComponentTarget (CBenchName n) _) = Just $ display n
 showBenchComponentTarget _ _ = Nothing
 
+isBenchComponentTarget :: ComponentTarget -> Bool
+isBenchComponentTarget (ComponentTarget (CBenchName _) _) = True
+isBenchComponentTarget _                                  = False
+
+isForeignLibComponentTarget :: ComponentTarget -> Bool
+isForeignLibComponentTarget (ComponentTarget (CFLibName _) _) = True
+isForeignLibComponentTarget _                                 = False
+
+isExeComponentTarget :: ComponentTarget -> Bool
+isExeComponentTarget (ComponentTarget (CExeName _) _ ) = True
+isExeComponentTarget _                                 = False
+
+isSubLibComponentTarget :: ComponentTarget -> Bool
+isSubLibComponentTarget (ComponentTarget (CSubLibName _) _) = True
+isSubLibComponentTarget _                                   = False
+
 ---------------------------
 -- Setup.hs script policy
 --