diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 6e592e1cc6a2609ae75c537015e3b6db86818099..1c0334629cfd35e5ce18037ed6f5ea9b8a37845f 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -117,6 +117,7 @@
 
 // Inter
 #define CIIP_PDPC                                         1 // apply pdpc to megre prediction as a new CIIP mode (CIIP_PDPC) additional to CIIP mode
+#define JVET_X0090_CIIP_FIX                               1 // JVET-X0090: combination of CIIP, OBMC and LMCS
 #define SAMPLE_BASED_BDOF                                 1 // Sample based BDOF
 #define MULTI_PASS_DMVR                                   1 // Multi-pass DMVR
 #define AFFINE_MMVD                                       1 // Add MMVD to affine merge mode
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index 34ec45f434927ad922be32e347fc87f66aed9101..b314e490a8fdfceee1cce3eb7494426b3a51b8dc 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -972,7 +972,11 @@ void DecCu::xReconInter(CodingUnit &cu)
   if (cu.firstPU->ciipFlag)
   {
     const UnitArea localUnitArea( cu.cs->area.chromaFormat, Area( 0, 0, cu.Y().width, cu.Y().height ) );
-
+#if ENABLE_OBMC && JVET_X0090_CIIP_FIX
+    cu.isobmcMC = true;
+    m_pcInterPred->subBlockOBMC(*cu.firstPU);
+    cu.isobmcMC = false;
+#endif
     if( cu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag() )
     {
       m_pcIntraPred->geneWeightedPred<true>( COMPONENT_Y, cu.cs->getPredBuf( *cu.firstPU ).Y(), *cu.firstPU, cu.cs->getPredBuf( *cu.firstPU ).Y(), m_ciipBuffer.getBuf( localUnitArea.Y() ), m_pcReshape->getFwdLUT().data() );
@@ -994,7 +998,14 @@ void DecCu::xReconInter(CodingUnit &cu)
   }
 #if ENABLE_OBMC
   cu.isobmcMC = true;
+#if JVET_X0090_CIIP_FIX
+  if (!cu.firstPU->ciipFlag)
+  {
+    m_pcInterPred->subBlockOBMC(*cu.firstPU);
+  }
+#else
   m_pcInterPred->subBlockOBMC(*cu.firstPU);
+#endif
   cu.isobmcMC = false;
 #endif
   DTRACE    ( g_trace_ctx, D_TMP, "pred " );
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index 30136d1cc5a57399a8fb3f2c3e25db18a5ecf617..1dfb92b2de39984646ba50781dd1cf1cdbc9c997 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -3918,6 +3918,40 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
 #else
           uint32_t bufIdx = 0;
 #endif
+#if JVET_X0090_CIIP_FIX
+          m_pcInterSearch->motionCompensation(pu);
+#if ENABLE_OBMC
+          cu.isobmcMC = true;
+          cu.obmcFlag = true;
+          m_pcInterSearch->subBlockOBMC(pu);
+          cu.isobmcMC = false;
+#endif
+          if (cu.cs->slice->getLmcsEnabledFlag() && m_pcReshape->getCTUFlag())
+          {
+            m_pcIntraSearch->geneWeightedPred<true>(COMPONENT_Y, tempCS->getPredBuf(pu).Y(), pu, tempCS->getPredBuf(pu).Y(), m_ciipBuffer[bufIdx].getBuf(localUnitArea.Y()), m_pcReshape->getFwdLUT().data());
+          }
+          else
+          {
+            m_pcIntraSearch->geneWeightedPred<false>(COMPONENT_Y, tempCS->getPredBuf(pu).Y(), pu, tempCS->getPredBuf(pu).Y(), m_ciipBuffer[bufIdx].getBuf(localUnitArea.Y()));
+          }
+
+#if INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
+          if (isChromaEnabled(pu.chromaFormat))
+#else
+          if (isChromaEnabled(pu.chromaFormat) && pu.chromaSize().width > 2)
+#endif
+          {
+            m_pcIntraSearch->geneWeightedPred<false>(COMPONENT_Cb, tempCS->getPredBuf(pu).Cb(), pu, tempCS->getPredBuf(pu).Cb(), m_ciipBuffer[bufIdx].getBuf(localUnitArea.Cb()));
+            m_pcIntraSearch->geneWeightedPred<false>(COMPONENT_Cr, tempCS->getPredBuf(pu).Cr(), pu, tempCS->getPredBuf(pu).Cr(), m_ciipBuffer[bufIdx].getBuf(localUnitArea.Cr()));
+          }
+#if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
+          else if (isChromaEnabled(pu.chromaFormat))
+          {
+            tempCS->getPredBuf().Cb().copyFrom(tempCS->getPredBuf(pu).Cb());
+            tempCS->getPredBuf().Cr().copyFrom(tempCS->getPredBuf(pu).Cr());
+          }
+#endif
+#else
           // Luma CIIP was already done in SATD check stage and stored
           tempCS->getPredBuf().Y().copyFrom( acMergeTempBuffer[uiMrgHADIdx]->Y() );
 
@@ -3936,6 +3970,7 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
             tempCS->getPredBuf().Cb().copyFrom(acMergeTmpBuffer[uiMergeCand].Cb());
             tempCS->getPredBuf().Cr().copyFrom(acMergeTmpBuffer[uiMergeCand].Cr());
           }
+#endif
 #endif
         }
         else
@@ -4078,7 +4113,14 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
 #if ENABLE_OBMC
       cu.isobmcMC = true;
       cu.obmcFlag = true;
+#if JVET_X0090_CIIP_FIX
+      if (!pu.ciipFlag)
+      {
+        m_pcInterSearch->subBlockOBMC(pu);
+      }
+#else
       m_pcInterSearch->subBlockOBMC( pu );
+#endif
       cu.isobmcMC = false;
 #endif