diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index 20eb18278f20f0c5d525b8c3334a93228e3a442b..d73772b84e0650fd2c359dcf46c4047ae950ce5b 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -305,6 +305,7 @@ class LLOcclusionCullingGroup : public LLViewerOctreeGroup
 	void checkOcclusion(); //read back last occlusion query (if any)
 	void doOcclusion(LLCamera* camera, const LLVector4a* shift = NULL); //issue occlusion query
 	BOOL isOcclusionState(U32 state) const	{ return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }
+	U32  getOcclusionState() const	{ return mOcclusionState[LLViewerCamera::sCurCameraID];}
 
 	BOOL needsUpdate();
 	U32  getLastOcclusionIssuedTime();
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 31722507ce9cf0742e4b77d7837baaef1890b8b9..65da1e854d1f978d01584a807bb116e027458309 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -412,7 +412,7 @@ bool LLVOCacheEntry::isAnyVisible(const LLVector4a& camera_origin, const LLVecto
 	}
 
 	//within the back sphere
-	if(!vis && !mParentID)
+	if(!vis && !mParentID && !group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
 	{
 		LLVector4a lookAt;
 
@@ -738,12 +738,28 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull
 class LLVOCacheOctreeBackCull : public LLViewerOctreeCull
 {
 public:
-	LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 pixel_threshold) 
-		: LLViewerOctreeCull(camera), mRegionp(regionp), mPixelThreshold(pixel_threshold)
+	LLVOCacheOctreeBackCull(LLCamera* camera, const LLVector3& shift, LLViewerRegion* regionp, F32 pixel_threshold, bool use_occlusion) 
+		: LLViewerOctreeCull(camera), mRegionp(regionp), mPixelThreshold(pixel_threshold), mUseObjectCacheOcclusion(use_occlusion)
 	{
 		mLocalShift = shift;
 		mSphereRadius = LLVOCacheEntry::sRearFarRadius;
 	}
+	
+	virtual bool earlyFail(LLViewerOctreeGroup* base_group)
+	{
+		if( mUseObjectCacheOcclusion &&
+			base_group->getOctreeNode()->getParent()) //never occlusion cull the root node
+		{
+			LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
+
+			if (group->getOcclusionState() > 0) //occlusion state is not clear.
+			{
+				return true;
+			}
+		}
+
+		return false;
+	}
 
 	virtual S32 frustumCheck(const LLViewerOctreeGroup* group)
 	{			
@@ -781,9 +797,10 @@ class LLVOCacheOctreeBackCull : public LLViewerOctreeCull
 	LLViewerRegion*  mRegionp;
 	LLVector3        mLocalShift; //shift vector from agent space to local region space.
 	F32              mPixelThreshold;
+	bool             mUseObjectCacheOcclusion;
 };
 
-void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold)
+void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold, bool use_occlusion)
 {
 	if(LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
 	{
@@ -804,7 +821,7 @@ void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold
 	//localize the camera
 	LLVector3 region_agent = mRegionp->getOriginAgent();
 	
-	LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, pixel_threshold);
+	LLVOCacheOctreeBackCull culler(&camera, region_agent, mRegionp, pixel_threshold, use_occlusion);
 	culler.traverse(mOctree);
 
 	mBackSlectionEnabled--;
@@ -855,7 +872,10 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
 		if(LLViewerOctreeEntryData::getCurrentFrame() % seed != mIdleHash)
 		{
 			mFrontCull = FALSE;
-			selectBackObjects(camera, LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull));//process back objects selection
+
+			//process back objects selection
+			selectBackObjects(camera, LLVOCacheEntry::getSquaredPixelThreshold(mFrontCull), 
+				do_occlusion && use_object_cache_occlusion);
 			return 0; //nothing changed, reduce frequency of culling
 		}
 	}
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 6e10ab86ee4cb997c09e8e66c85ff33b2e5d2d85..6af38e5b7c31bae3979b042dd137aa4cffb82b0b 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -195,7 +195,7 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr
 	bool isFrontCull() const {return mFrontCull;}
 
 private:
-	void selectBackObjects(LLCamera &camera, F32 projection_area_cutoff); //select objects behind camera.
+	void selectBackObjects(LLCamera &camera, F32 projection_area_cutoff, bool use_occlusion); //select objects behind camera.
 
 public:
 	static BOOL sNeedsOcclusionCheck;