diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index 21cac60fe204c4183c37a05380d66773e434a59f..506d65d77a62200abfba861f33c57e2a063ef84c 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -566,7 +566,11 @@ void InterPrediction::destroy()
 
 #if INTER_LIC || (TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM) || JVET_W0090_ARMC_TM || JVET_Z0056_GPM_SPLIT_MODE_REORDERING || JVET_Z0061_TM_OBMC
 #if JVET_Z0153_IBC_EXT_REF
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+void InterPrediction::init( RdCost* pcRdCost, ChromaFormat chromaFormatIDC, const int ctuSize, Reshape* reshape, const int picWidth, const int picHeight )
+#else
 void InterPrediction::init( RdCost* pcRdCost, ChromaFormat chromaFormatIDC, const int ctuSize, Reshape* reshape, const int picWidth )
+#endif
 #else
 void InterPrediction::init( RdCost* pcRdCost, ChromaFormat chromaFormatIDC, const int ctuSize, Reshape* reshape )
 #endif
@@ -853,12 +857,16 @@ void InterPrediction::init( RdCost* pcRdCost, ChromaFormat chromaFormatIDC, cons
 #if JVET_Z0118_GDR
 #if JVET_Z0153_IBC_EXT_REF
   m_ibcBufferWidth  = (picWidth + ctuSize - 1) / ctuSize * ctuSize;
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  m_ibcBufferHeight = (picHeight + ctuSize - 1) / ctuSize * ctuSize;
+#else
   m_ibcBufferHeight = 3 * ctuSize;
 #if JVET_AA0106_IBCBUF_CTU256
     if( 256 == ctuSize )
     {
       m_ibcBufferHeight = 2 * ctuSize;
     }
+#endif
 #endif
 
   if (m_ibcBuffer0.bufs.empty())
diff --git a/source/Lib/CommonLib/InterPrediction.h b/source/Lib/CommonLib/InterPrediction.h
index 4b48043137a3a3c1c2ff9c6a0bc7f85ea49e4271..fd9e5139eb8bd2e96b68b6b5e775b4ab4c2edbca 100644
--- a/source/Lib/CommonLib/InterPrediction.h
+++ b/source/Lib/CommonLib/InterPrediction.h
@@ -648,7 +648,11 @@ public:
 
 #if INTER_LIC || (TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM) || JVET_W0090_ARMC_TM || JVET_Z0056_GPM_SPLIT_MODE_REORDERING || JVET_Z0061_TM_OBMC
 #if JVET_Z0153_IBC_EXT_REF
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  void    init                (RdCost* pcRdCost, ChromaFormat chromaFormatIDC, const int ctuSize, Reshape* reshape, const int picWidth, const int picHeight);
+#else
   void    init                (RdCost* pcRdCost, ChromaFormat chromaFormatIDC, const int ctuSize, Reshape* reshape, const int picWidth);
+#endif
 #else
   void    init                (RdCost* pcRdCost, ChromaFormat chromaFormatIDC, const int ctuSize, Reshape* reshape);
 #endif
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index b01dc83f23ccbbe8dc85723022eff69c152c357d..4e132f78c0cf89d346a997752c0b1f695e89ea10 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1894,6 +1894,10 @@ private:
 #endif
 #endif
 
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  bool              m_largeIBCLSR;
+#endif
+
 #if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
   bool              m_LadfEnabled;
   int               m_LadfNumIntervals;
@@ -2669,6 +2673,10 @@ void                    setCCALFEnabledFlag( bool b )
 #if JVET_AH0066_JVET_AH0202_CCP_MERGE_LUMACBF0
   void      setUseInterCcpMergeZeroLumaCbf   ( bool b )                              { m_interCcpMergeZeroLumaCbf = b; }
   bool      getUseInterCcpMergeZeroLumaCbf   ()                           const      { return m_interCcpMergeZeroLumaCbf; }
+#endif
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  void      setUseLargeIBCLSR   ( bool b )                                           { m_largeIBCLSR = b; }
+  bool      getUseLargeIBCLSR   ()                                        const      { return m_largeIBCLSR; }
 #endif
   void      setUseMRL             ( bool b )                                        { m_MRL = b; }
   bool      getUseMRL             ()                                      const     { return m_MRL; }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 1ede9be2a2950c0ec242f0ba37d1c63e524a4368..c2c5e192c06ced35c0536cd3819d17e6a412e109 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -258,6 +258,7 @@
 #define JVET_AG0091_ARBVP                                 1 // JVET-AG0091: Auto-relocated block vector prediction
 #define JVET_AI0082_TEMPORAL_BV                           1 // JVET-AI0081: Temporal BV for IBC merge list construction
 #define JVET_AJ0096_SATD_REORDER_INTRA                    1 // JVET-AJ0096: SATD-based reordering for intra coding
+#define JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA               1 // JVET-AJ0172: Unified reference area of IBC and IntraTMP
 
 #if JVET_AC0071_DBV && JVET_V0130_INTRA_TMP
 #define JVET_AF0066_ENABLE_DBV_4_SINGLE_TREE              1 // JVET-AF0066: Enable DBV mode in single tree configuration
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 15adfcfcceaa6a51cd40dbadd61671c5f8394bfc..c44b9b1a3f1a687bd3a79aaa222718466ee90dab 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -8827,7 +8827,7 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h
   const int ctuSizeLog2 = floorLog2(ctuSize);
 
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
-#if JVET_AC0071_DBV
+#if JVET_AC0071_DBV && !JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
   const bool isDBV = (pu.cs->slice->getSliceType() == I_SLICE && ( CS::isDualITree(*pu.cs) || (pu.cu->isSST && pu.cu->separateTree) ) && pu.cu->slice->getSPS()->getUseIntraDBV())
 #else
@@ -8969,6 +8969,12 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h
     return false;
   }
 
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  if (((refTopY >> ctuSizeLog2) == (yPos >> ctuSizeLog2)) && ((refRightX >> ctuSizeLog2) > (xPos >> ctuSizeLog2)))
+  {
+    return false;
+  }
+#else
 #if JVET_Z0084_IBC_TM || JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
   unsigned curTileIdx = pu.cs->pps->getTileIdx(Position(xPos, yPos));
 #else
@@ -9107,6 +9113,7 @@ bool PU::searchBv(const PredictionUnit& pu, int xPos, int yPos, int width, int h
 #endif
 #if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS && JVET_AC0071_DBV
   }
+#endif
 #endif
 
   // in the same CTU, or valid area from left CTU. Check if the reference block is already coded
@@ -19302,6 +19309,12 @@ inline void PU::getRribcBvpCand(PredictionUnit &pu, AMVPInfo *pInfo)
   }
   else if (pu.cu->rribcFlipType == 2)
   {
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+    pInfo->mvCand[0] = Mv(0, std::max(-static_cast<int>(pu.lheight()), -pu.Y().y));
+    pInfo->mvCand[0].changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL);
+    pInfo->mvCand[1] = Mv(0, - pu.Y().y);
+    pInfo->mvCand[1].changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL);
+#else
     const int ctbSize     = pu.cs->sps->getCTUSize();
     const int numCurrCtuY = (pu.Y().y >> (floorLog2(ctbSize)));
     unsigned int lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth();
@@ -19318,6 +19331,7 @@ inline void PU::getRribcBvpCand(PredictionUnit &pu, AMVPInfo *pInfo)
     pInfo->mvCand[0].changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL);
     pInfo->mvCand[1] = Mv(0,rrTop);
     pInfo->mvCand[1].changePrecision(MV_PRECISION_INT, MV_PRECISION_INTERNAL);
+#endif
   }
 }
 #endif
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index 855ef3a4d52665b351077c5222667a0289f58441..b6d14b321e96f237a5feec76e86a2e88f3bd8d24 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -111,7 +111,7 @@ void DecCu::decompressCtu( CodingStructure& cs, const UnitArea& ctuArea )
     m_pcInterPred->resetIBCBuffer(cs.pcv->chrFormat, cs.slice->getSPS()->getMaxCUHeight());
     cs.resetIBCBuffer = false;
   }
-#if JVET_Z0153_IBC_EXT_REF
+#if JVET_Z0153_IBC_EXT_REF && !JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
   else
   {
     const int ctuSize = cs.slice->getSPS()->getMaxCUHeight();
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index ed2f1760263be33a5e44741b24b238170cd59ee7..82223c1df013107d5a3b10cd4e7d70537795293e 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -1111,7 +1111,11 @@ void DecLib::finishPicture(int& poc, PicList*& rpcListPic, MsgLevel msgl )
   m_pcPic->cs->destroyTemporaryCsData();
 #if JVET_AA0096_MC_BOUNDARY_PADDING
   m_cFrameMcPadPrediction.init(&m_cRdCost, pcSlice->getSPS()->getChromaFormatIdc(), pcSlice->getSPS()->getMaxCUHeight(),
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+                               NULL, m_pcPic->getPicWidthInLumaSamples(),m_pcPic->getPicHeightInLumaSamples());
+#else
                                NULL, m_pcPic->getPicWidthInLumaSamples());
+#endif
   m_cFrameMcPadPrediction.mcFramePad(m_pcPic, *(m_pcPic->slices[0]));
 #endif
 
@@ -1967,7 +1971,11 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
     m_cIntraPred.init( sps->getChromaFormatIdc(), sps->getBitDepth( CHANNEL_TYPE_LUMA ) );
 #if INTER_LIC || (TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM) || JVET_W0090_ARMC_TM || JVET_Z0056_GPM_SPLIT_MODE_REORDERING
 #if JVET_Z0153_IBC_EXT_REF
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+    m_cInterPred.init(&m_cRdCost, sps->getChromaFormatIdc(), sps->getMaxCUHeight(), &m_cReshaper, sps->getMaxPicWidthInLumaSamples(),sps->getMaxPicHeightInLumaSamples());
+#else
     m_cInterPred.init(&m_cRdCost, sps->getChromaFormatIdc(), sps->getMaxCUHeight(), &m_cReshaper, sps->getMaxPicWidthInLumaSamples());
+#endif
 #else
     m_cInterPred.init( &m_cRdCost, sps->getChromaFormatIdc(), sps->getMaxCUHeight(), &m_cReshaper);
 #endif
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 8e924473585e14471184d30186bae941d6796dff..1d8c0cd314828a9799ab8705417a21dcea192484 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -4838,7 +4838,11 @@ void EncGOP::compressGOP(int iPOCLast, int iNumPicRcvd, PicList &rcListPic, std:
     pcPic->cs->destroyTemporaryCsData();
 #if JVET_AA0096_MC_BOUNDARY_PADDING
     m_pcFrameMcPadPrediction->init(m_pcEncLib->getRdCost(), pcSlice->getSPS()->getChromaFormatIdc(),
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+                                   pcSlice->getSPS()->getMaxCUHeight(), NULL, pcPic->getPicWidthInLumaSamples(),pcPic->getPicHeightInLumaSamples());
+#else
                                    pcSlice->getSPS()->getMaxCUHeight(), NULL, pcPic->getPicWidthInLumaSamples());
+#endif
     m_pcFrameMcPadPrediction->mcFramePad(pcPic, *(pcPic->slices[0]));
     m_pcFrameMcPadPrediction->destroy();
 #endif
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 0450da4efcf484a8300309d836a727c4c99b3d9b..d3209d48c5d0393c47f9c28c089ee38f79578fb2 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -751,6 +751,9 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf )
                      , &m_cReshaper
 #if JVET_Z0153_IBC_EXT_REF
                      , pps0.getPicWidthInLumaSamples()
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+                     , pps0.getPicHeightInLumaSamples()
+#endif
 #endif
   );
 
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index bf9b6f559cb84b213ba7473a14b0c5716dd3b0df..b61088704df6c3edfa2c90cd38390d6d0b9791fc 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1925,7 +1925,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
 
     prevQP[0] = prevQP[1] = pcSlice->getSliceQp();
 
-#if (JVET_AC0335_CONTENT_ADAPTIVE_OBMC_ENABLING && ENABLE_OBMC) || JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS || JVET_AH0066_JVET_AH0202_CCP_MERGE_LUMACBF0
+#if (JVET_AC0335_CONTENT_ADAPTIVE_OBMC_ENABLING && ENABLE_OBMC) || JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS || JVET_AH0066_JVET_AH0202_CCP_MERGE_LUMACBF0 || JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
     int hashBlkHitPerc = -1;
 #endif
 
@@ -2008,6 +2008,15 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
   }
 #endif
 
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  if (cs.slice->getPOC() == 0 || cs.slice->getSliceType() == I_SLICE) // ensure sequential and parallel simulation generate same output
+  {
+    hashBlkHitPerc = (hashBlkHitPerc == -1) ? m_pcCuEncoder->getIbcHashMap().calHashBlkMatchPerc(cs.area.Y()) : hashBlkHitPerc;
+    SPS* spsTmp = const_cast<SPS*>(cs.sps);
+    spsTmp->setUseLargeIBCLSR(hashBlkHitPerc > 56);
+  }
+#endif
+
 #if JVET_AH0209_PDP
   if( m_pcCuEncoder->getEncCfg()->getUsePDP() )
   {
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index 2c6d16ed975d5ecf6a75fbe9798a774f1501ca7c..05a4785072ddc40780d1d0bf356826b210d270f1 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -440,6 +440,9 @@ void InterSearch::init( EncCfg*        pcEncCfg,
                       , EncReshape*    pcReshape
 #if JVET_Z0153_IBC_EXT_REF
                       , const uint32_t curPicWidthY 
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+                      , const uint32_t curPicHeightY 
+#endif
 #endif
 )
 {
@@ -494,7 +497,11 @@ void InterSearch::init( EncCfg*        pcEncCfg,
   const ChromaFormat cform = pcEncCfg->getChromaFormatIdc();
 #if INTER_LIC || (TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM) || JVET_W0090_ARMC_TM || JVET_Z0056_GPM_SPLIT_MODE_REORDERING
 #if JVET_Z0153_IBC_EXT_REF
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  InterPrediction::init( pcRdCost, cform, maxCUHeight, m_pcReshape, curPicWidthY, curPicHeightY );
+#else
   InterPrediction::init( pcRdCost, cform, maxCUHeight, m_pcReshape, curPicWidthY );
+#endif
 #else
   InterPrediction::init( pcRdCost, cform, maxCUHeight, m_pcReshape );
 #endif
@@ -1984,7 +1991,11 @@ void InterSearch::xIntraPatternSearch(PredictionUnit &pu, IntTZSearchStruct &cSt
 #endif
     {
 #if JVET_Z0153_IBC_EXT_REF
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+      int verTop = pu.cu->slice->getSPS()->getUseLargeIBCLSR()? -(int)lcuWidth * 2:- (int)lcuWidth;
+#else
       int verTop = - (int)lcuWidth;
+#endif
       int verBottom = std::min((int)(lcuWidth>>2), (int)(lcuWidth - (cuPelY % lcuWidth) - roiHeight));
       int horLeft = - (int)lcuWidth*2;
       int horRight = lcuWidth>>2;
@@ -3206,12 +3217,16 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR
   const int picWidth = pu.cs->slice->getPPS()->getPicWidthInLumaSamples();
 
   srLeft = -cuPelX;
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  srTop = -cuPelY;
+#else
   srTop = - 2 * lcuWidth - (cuPelY % lcuWidth);
 #if JVET_AA0106_IBCBUF_CTU256
   if (256 == lcuWidth)
   {
     srTop = -lcuWidth - (cuPelY % lcuWidth);
   }
+#endif
 #endif
   srRight = picWidth - cuPelX - iRoiWidth;
   srBottom = lcuWidth - (cuPelY % lcuWidth) - iRoiHeight;  
@@ -4952,6 +4967,11 @@ inline void InterSearch::getBestBvpBvOneZeroComp(PredictionUnit &pu, Mv cMv, Dis
   }
   else if (cMv.getHor() == 0)
   {
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+    bvpCand[0] = Mv(0, std::max(-(int) pu.lheight(), -pu.Y().y));
+    bvpCand[1] = Mv(0, -pu.Y().y);
+    bvOneZeroCompCost = m_pcRdCost->getBvHorZeroCompCost(cMv.getVer(), pu.cs->sps->getAMVREnabledFlag(), &tempImv, &tempIdx, bvpCand);
+#else
     const int ctbSize     = pu.cs->sps->getCTUSize();
     const int numCurrCtuY = (pu.Y().y >> (floorLog2(ctbSize)));
     unsigned int lcuWidth = pu.cs->slice->getSPS()->getMaxCUWidth();
@@ -4967,6 +4987,7 @@ inline void InterSearch::getBestBvpBvOneZeroComp(PredictionUnit &pu, Mv cMv, Dis
     bvpCand[0] = Mv(0, std::max(-(int) pu.lheight(), rrTop));
     bvpCand[1] = Mv(0, rrTop);
     bvOneZeroCompCost = m_pcRdCost->getBvHorZeroCompCost(cMv.getVer(), pu.cs->sps->getAMVREnabledFlag(), &tempImv, &tempIdx, bvpCand);
+#endif
   }
 
   if (bvOneZeroCompCost < initCost)
@@ -16980,6 +17001,12 @@ bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, in
     return false;
   }
 
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+  if (((refTopY >> ctuSizeLog2) == (yPos >> ctuSizeLog2)) && ((refRightX >> ctuSizeLog2) > (xPos >> ctuSizeLog2)))
+  {
+    return false;
+  }
+#else
   unsigned curTileIdx = pu.cs->pps->getTileIdx(pu.lumaPos());
   unsigned refTileIdx = pu.cs->pps->getTileIdx(Position(refLeftX, refTopY));
   if (curTileIdx != refTileIdx)
@@ -17079,6 +17106,7 @@ bool InterSearch::searchBv(PredictionUnit& pu, int xPos, int yPos, int width, in
   }
   else
     return false;
+#endif
 #endif
 
   // in the same CTU, or valid area from left CTU. Check if the reference block is already coded
diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h
index a4cd38d844534d97e2e39373d73424a856fda1cf..03efa5c8d848f763bf544bcbe8803fbebbaf9dc3 100644
--- a/source/Lib/EncoderLib/InterSearch.h
+++ b/source/Lib/EncoderLib/InterSearch.h
@@ -974,6 +974,9 @@ public:
                                      , EncReshape*   m_pcReshape
 #if JVET_Z0153_IBC_EXT_REF
                                     , const uint32_t curPicWidthY
+#if JVET_AJ0172_IBC_ITMP_ALIGN_REF_AREA
+                                    , const uint32_t curPicHeightY 
+#endif
 #endif
                                     );