diff --git a/cfg/encoder_intra_vtm.cfg b/cfg/encoder_intra_vtm.cfg
index 1b99e0e8dbc12cdf6f69fea33f2ad7c92ed00f6d..15be552017abcc28f6d20a59eb91ec2d96e82ec0 100644
--- a/cfg/encoder_intra_vtm.cfg
+++ b/cfg/encoder_intra_vtm.cfg
@@ -98,6 +98,7 @@ MTS                          : 1
 MTSIntraMaxCand              : 3
 MTSInterMaxCand              : 4
 SBT                          : 1
+ISP                          : 1
 Affine                       : 1
 SubPuMvp                     : 1
 MaxNumMergeCand              : 6
diff --git a/cfg/encoder_lowdelay_P_vtm.cfg b/cfg/encoder_lowdelay_P_vtm.cfg
index e56edd9a6c39beadab9e0419a3b0c12aacab2b67..4cdf507662492284131234caa2e418ff716aa66c 100644
--- a/cfg/encoder_lowdelay_P_vtm.cfg
+++ b/cfg/encoder_lowdelay_P_vtm.cfg
@@ -114,6 +114,7 @@ MTS                          : 1
 MTSIntraMaxCand              : 3
 MTSInterMaxCand              : 4
 SBT                          : 1
+ISP                          : 1
 Affine                       : 1
 SubPuMvp                     : 1
 MaxNumMergeCand              : 6
diff --git a/cfg/encoder_lowdelay_vtm.cfg b/cfg/encoder_lowdelay_vtm.cfg
index d5bd1e79e40d53acf68de48d3adfbb28d127f15e..bbf67b4ed0bc05ef1ea6c726c4d51face92bcd5e 100644
--- a/cfg/encoder_lowdelay_vtm.cfg
+++ b/cfg/encoder_lowdelay_vtm.cfg
@@ -114,6 +114,7 @@ MTS                          : 1
 MTSIntraMaxCand              : 3
 MTSInterMaxCand              : 4
 SBT                          : 1
+ISP                          : 1
 Affine                       : 1
 SubPuMvp                     : 1
 MaxNumMergeCand              : 6
diff --git a/cfg/encoder_randomaccess_vtm.cfg b/cfg/encoder_randomaccess_vtm.cfg
index 2fdc284ae68c0f15c29469395d9a288c6ae54b10..7bfe101b0ddf8249a48e716f08f9596fd7cf3633 100644
--- a/cfg/encoder_randomaccess_vtm.cfg
+++ b/cfg/encoder_randomaccess_vtm.cfg
@@ -128,6 +128,7 @@ MTS                          : 1
 MTSIntraMaxCand              : 3
 MTSInterMaxCand              : 4
 SBT                          : 1
+ISP                          : 1
 Affine                       : 1
 SubPuMvp                     : 1
 MaxNumMergeCand              : 6
diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index 85fa51c79b802b4c7806ce613e3b0b4715758839..5676da3a67e9db953a514f897c538badd7ca333a 100644
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -1771,6 +1771,20 @@ Enables or disables the use of a deblocking across tile boundaries.
 Enables or disables the use of asymmetric motion partitions.
 \\
 
+\Option{ISP} &
+%\ShortOption{\None} &
+\Default{false} &
+Enables or disables the Intra Sub-Partitions coding mode.
+\\
+
+\Option{ISPFast} &
+%\ShortOption{\None} &
+\Default{false} &
+Enables or disables reduced testing of non-DCT-II transforms if ISP is likely to become the best mode for a given CU.
+\par
+This option has no effect if either ISP or MTS are disabled.
+\\
+
 \Option{SAO} &
 %\ShortOption{\None} &
 \Default{true} &
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index cfda65bae7212fe3750aba37133e546aaa0d3ae2..30e1560ad73e2a509ecf9d164a67689c848fef5d 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -346,6 +346,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setUseBLambdaForNonKeyLowDelayPictures               ( m_bUseBLambdaForNonKeyLowDelayPictures );
   m_cEncLib.setPCMLog2MinSize                                    ( m_uiPCMLog2MinSize);
   m_cEncLib.setUsePCM                                            ( m_usePCM );
+#if INCLUDE_ISP_CFG_FLAG
+  m_cEncLib.setUseISP                                            ( m_ISP );
+#endif
   m_cEncLib.setUseFastISP                                        ( m_useFastISP );
 
   // set internal bit-depth and constants
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 9ba6eecc0f39e1da55a49d6653ea20a33cc90e56..0ce37b0db16cca1870c6722203ab268e4a8271e3 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -857,6 +857,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("MTSInterMaxCand",                                 m_MTSInterMaxCand,                                    4, "Number of additional candidates to test in encoder search for MTS in inter slices\n")
   ("MTSImplicit",                                     m_MTSImplicit,                                        0, "Enable implicit MTS (when explicit MTS is off)\n")
   ( "SBT",                                            m_SBT,                                            false, "Enable Sub-Block Transform for inter blocks\n" )
+#if INCLUDE_ISP_CFG_FLAG
+  ( "ISP",                                            m_ISP,                                            false, "Enable Intra Sub-Partitions\n" )
+#endif
 #if JVET_N0235_SMVD_SPS
   ("SMVD",                                            m_SMVD,                                           false, "Enable Symmetric MVD\n")
 #endif
@@ -3147,6 +3150,9 @@ void EncAppCfg::xPrintParameter()
     }
     msg( VERBOSE, "MTS: %1d(intra) %1d(inter) ", m_MTS & 1, ( m_MTS >> 1 ) & 1 );
     msg( VERBOSE, "SBT:%d ", m_SBT );
+#if INCLUDE_ISP_CFG_FLAG
+    msg( VERBOSE, "ISP:%d ", m_ISP );
+#endif
 #if JVET_N0235_SMVD_SPS
     msg( VERBOSE, "SMVD:%d ", m_SMVD );
 #endif
@@ -3188,7 +3194,11 @@ void EncAppCfg::xPrintParameter()
   msg( VERBOSE, "PBIntraFast:%d ", m_usePbIntraFast );
   if( m_ImvMode ) msg( VERBOSE, "IMV4PelFast:%d ", m_Imv4PelFast );
   if( m_MTS ) msg( VERBOSE, "MTSMaxCand: %1d(intra) %1d(inter) ", m_MTSIntraMaxCand, m_MTSInterMaxCand );
+#if INCLUDE_ISP_CFG_FLAG
+  if( m_ISP ) msg( VERBOSE, "ISPFast:%d ", m_useFastISP );
+#else
   msg( VERBOSE, "ISPFast:%d ", m_useFastISP );
+#endif
   msg( VERBOSE, "AMaxBT:%d ", m_useAMaxBT );
   msg( VERBOSE, "E0023FastEnc:%d ", m_e0023FastEnc );
   msg( VERBOSE, "ContentBasedFastQtbt:%d ", m_contentBasedFastQtbt );
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 51ae1a97415fd332811fef84cddedd8b3237a59c..32cd865f1fda9f995017a2d7ab2813081d349593 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -178,6 +178,9 @@ protected:
   bool      m_rdpcmEnabledFlag[NUMBER_OF_RDPCM_SIGNALLING_MODES];///< control flags for residual DPCM
   bool      m_persistentRiceAdaptationEnabledFlag;            ///< control flag for Golomb-Rice parameter adaptation over each slice
   bool      m_cabacBypassAlignmentEnabledFlag;
+#if INCLUDE_ISP_CFG_FLAG
+  bool      m_ISP;
+#endif
   bool      m_useFastISP;                                    ///< flag for enabling fast methods for ISP
 
   // coding quality
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index dfdd7feb87b28840b0fe0d6fa8d415e83f32fcdb..d1d8b8ccf45efa257ff84f87d061e0f2c2af5dd3 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -1788,6 +1788,9 @@ SPS::SPS()
 , m_DMVR                      ( false )
 , m_SBT                       ( false )
 , m_MaxSbtSize                ( 32 )
+#if INCLUDE_ISP_CFG_FLAG
+, m_ISP                       ( false )
+#endif
 #if HEVC_VPS
 , m_VPSId                     (  0)
 #endif
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index 2d6e84a6c9c7dd33fdba750b69decb4d673a0995..4d8c2b443b34cfa662de87a8ee83f586baca4d35 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1014,6 +1014,9 @@ private:
   bool              m_DMVR;
   bool              m_SBT;
   uint8_t           m_MaxSbtSize;
+#if INCLUDE_ISP_CFG_FLAG
+  bool              m_ISP;
+#endif
 #if HEVC_VPS
   int               m_VPSId;
 #endif
@@ -1357,6 +1360,10 @@ public:
   unsigned                getIBCFlag() const                                                              { return m_IBCFlag; }
   void                    setUseSBT( bool b )                                                             { m_SBT = b; }
   bool                    getUseSBT() const                                                               { return m_SBT; }
+#if INCLUDE_ISP_CFG_FLAG
+  void                    setUseISP( bool b )                                                             { m_ISP = b; }
+  bool                    getUseISP() const                                                               { return m_ISP; }
+#endif
   void                    setMaxSbtSize( uint8_t val )                                                    { m_MaxSbtSize = val; }
   uint8_t                 getMaxSbtSize() const                                                           { return m_MaxSbtSize; }
 
diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp
index 8c701503e3009991f614e59fe2978e5dec32badd..5fb8639cec53913731a467c5d858552654fb307f 100644
--- a/source/Lib/CommonLib/TrQuant.cpp
+++ b/source/Lib/CommonLib/TrQuant.cpp
@@ -705,8 +705,11 @@ void TrQuant::transformNxN( TransformUnit &tu, const ComponentID &compID, const
 void TrQuant::xGetCoeffEnergy( TransformUnit &tu, const ComponentID &compID, const CoeffBuf& coeffs, double* diagRatio, double* horVerRatio )
 {
   if( nullptr == diagRatio || nullptr == horVerRatio ) return;
-
+#if INCLUDE_ISP_CFG_FLAG
+  if( tu.cu->predMode == MODE_INTRA && !tu.cu->ispMode && isLuma( compID ) && tu.cs->sps->getUseISP() && CU::canUseISPSplit( *tu.cu, compID ) != NOT_INTRA_SUBPARTITIONS )
+#else
   if( tu.cu->predMode == MODE_INTRA && !tu.cu->ispMode && isLuma( compID ) && CU::canUseISPSplit( *tu.cu, compID ) != NOT_INTRA_SUBPARTITIONS )
+#endif
   {
     const int width   = tu.cu->blocks[compID].width;
     const int height  = tu.cu->blocks[compID].height;
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 0733b52db2f6f57b5fa7aaa573556322da778452..a886796cee8af1698c4b39aa667de54f43073995 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -152,6 +152,7 @@ typedef std::pair<int, bool> TrMode;
 typedef std::pair<int, int>  TrCost;
 
 // clang-format off
+#define INCLUDE_ISP_CFG_FLAG                              1
 #define ENABLE_JVET_L0283_MRL                             1 // 1: Enable MRL, 0: Disable MRL
 #define JVET_L0090_PAIR_AVG                               1 // Add pairwise average candidates, replace HEVC combined candidates
 #define REUSE_CU_RESULTS                                  1
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index b06830023aa24aedb7733c3ab8366bf55a0f581e..657c4afcb6a5270a4fbc6ef80bd3b476c0da4928 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -2562,7 +2562,11 @@ void CABACReader::mts_coding( TransformUnit& tu, ComponentID compID )
 
 void CABACReader::isp_mode( CodingUnit& cu )
 {
+#if INCLUDE_ISP_CFG_FLAG
+  if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() )
+#else
   if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm )
+#endif
   {
     cu.ispMode = NOT_INTRA_SUBPARTITIONS;
     return;
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 463e93473d2d20f212822cf2f37b4d7761aecd8b..941614bd558db9a9a5408e49008a7e11eb95d475 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -1143,6 +1143,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
   }
   // KJS: not in draft yet
   READ_FLAG(uiCode, "sps_reshaper_enable_flag");                   pcSPS->setUseReshaper(uiCode == 1);
+#if INCLUDE_ISP_CFG_FLAG
+  READ_FLAG(uiCode, "isp_enable_flag");                            pcSPS->setUseISP(uiCode != 0);
+#endif
 
 #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
   READ_FLAG( uiCode, "sps_ladf_enabled_flag" );                     pcSPS->setLadfEnabled( uiCode != 0 );
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index ce9c579f52f8d7d3e3c83c8fa61c924a1b32dbd1..c4c4238fea67a49615cfb23c7ea7f85ae17936e4 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -2467,7 +2467,11 @@ void CABACWriter::mts_coding( const TransformUnit& tu, ComponentID compID )
 
 void CABACWriter::isp_mode( const CodingUnit& cu )
 {
+#if INCLUDE_ISP_CFG_FLAG
+  if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() )
+#else
   if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm )
+#endif
   {
     CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "error: cu.intraSubPartitions != 0" );
     return;
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 50bef16364872900d5563b8163ce61109b852b93..d4934fe5ab225370875316ad109b37eb77e32864 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -373,6 +373,9 @@ protected:
   int*      m_aidQP;
   uint32_t      m_uiDeltaQpRD;
   bool      m_bFastDeltaQP;
+#if INCLUDE_ISP_CFG_FLAG
+  bool      m_ISP;
+#endif
   bool      m_useFastISP;
 
   bool      m_bUseConstrainedIntraPred;
@@ -799,7 +802,10 @@ public:
   unsigned  getWrapAroundOffset             ()         const { return m_wrapAroundOffset; }
 
   // ADD_NEW_TOOL : (encoder lib) add access functions here
-
+#if INCLUDE_ISP_CFG_FLAG
+  void      setUseISP                       ( bool b )       { m_ISP = b; }
+  bool      getUseISP                       ()         const { return m_ISP; }
+#endif
   void      setReshaper                     ( bool b )                   { m_lumaReshapeEnable = b; }
   bool      getReshaper                     () const                     { return m_lumaReshapeEnable; }
   void      setReshapeSignalType            ( uint32_t signalType )      { m_reshapeSignalType = signalType; }
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 97d0d66e3cfa966286acaabf92a79ad478ee1134..58979e064384b022f7a07d096af4fbf75c183f7c 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -987,6 +987,9 @@ void EncLib::xInitSPS(SPS &sps)
   sps.setWrapAroundEnabledFlag                      ( m_wrapAround );
   sps.setWrapAroundOffset                   ( m_wrapAroundOffset );
   // ADD_NEW_TOOL : (encoder lib) set tool enabling flags and associated parameters here
+#if INCLUDE_ISP_CFG_FLAG
+  sps.setUseISP                             ( m_ISP );
+#endif
   sps.setUseReshaper                        ( m_lumaReshapeEnable );
   int minCUSize =  sps.getMaxCUWidth() >> sps.getLog2DiffMaxMinCodingBlockSize();
   int log2MinCUSize = 0;
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index a1817bf964c2af31427d7bfa5b0c3c9bbb62d805..87ac113447830320251095ade9fcb601ff375a12 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -292,7 +292,11 @@ void IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner,
 
   const int width   = partitioner.currArea().lwidth();
   const int height  = partitioner.currArea().lheight();
+#if INCLUDE_ISP_CFG_FLAG
+  int nOptionsForISP = sps.getUseISP() ? NUM_INTRA_SUBPARTITIONS_MODES : 1;
+#else
   int nOptionsForISP = NUM_INTRA_SUBPARTITIONS_MODES;
+#endif
   double bestCurrentCost = bestCostSoFar;
 
   int ispOptions[NUM_INTRA_SUBPARTITIONS_MODES] = { 0 };
@@ -1607,7 +1611,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp
 
   const bool           bUseCrossCPrediction = pps.getPpsRangeExtension().getCrossComponentPredictionEnabledFlag() && isChroma( compID ) && PU::isChromaIntraModeCrossCheckMode( pu ) && checkCrossCPrediction;
   const bool           ccUseRecoResi        = m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate();
+#if INCLUDE_ISP_CFG_FLAG
+  const bool           ispSplitIsAllowed    = sps.getUseISP() && CU::canUseISPSplit( *tu.cu, compID );
+#else
   const bool           ispSplitIsAllowed    = CU::canUseISPSplit( *tu.cu, compID );
+#endif
 
 
   //===== init availability pattern =====
@@ -1752,9 +1760,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp
     tu.mtsIdx = trModes->at(0).first;
   }
   m_pcTrQuant->transformNxN( tu, compID, cQP, uiAbsSum, m_CABACEstimator->getCtx(), loadTr, &diagRatio, &horVerRatio );
-  if (!tu.cu->ispMode && isLuma(compID) && ispSplitIsAllowed &&
-    tu.mtsIdx == 0
-    )
+#if INCLUDE_ISP_CFG_FLAG
+    if ( !tu.cu->ispMode && isLuma(compID) && ispSplitIsAllowed && tu.mtsIdx == 0 && ispSplitIsAllowed )
+#else
+  if ( !tu.cu->ispMode && isLuma(compID) && ispSplitIsAllowed && tu.mtsIdx == 0 )
+#endif
   {
     m_intraModeDiagRatio        .push_back(diagRatio);
     m_intraModeHorVerRatio      .push_back(horVerRatio);
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index b88af1ea55adfb4d8cd6ef50d8a7489faff52551..7e565d6594c283f005b9f5d371ca75436bc9c4bb 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -794,6 +794,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   }
   // KJS: not in draft yet
   WRITE_FLAG(pcSPS->getUseReshaper() ? 1 : 0, "sps_reshaper_enable_flag");
+#if INCLUDE_ISP_CFG_FLAG
+  WRITE_FLAG( pcSPS->getUseISP() ? 1 : 0,                                             "isp_enable_flag");
+#endif
 
 #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
   WRITE_FLAG( pcSPS->getLadfEnabled() ? 1 : 0,                                                 "sps_ladf_enabled_flag" );